1.js语句
1.1.条件语句
switch语句
switch (expression){
case expression1:
statements;
break;
default:
statements;
break;
}
case表达式expression1通常是数字和字符串,但标准运行case表达式也可以是其他类型,在expression和case表达式expression1比较的时候,使用的是恒等号===,所以不会有类型转换。
1.2.跳转语句
break和continue是js里面唯一可以使用label的语句
break lable1;
continue lable2;
如果我们希望break语句跳出非就近的循环体或switch语句时,就用得着这样的标签。
continue也有类似的情况。
2.js对象
2.0.几个词汇解释
2.0.1.
here are some terms we’ll use to distinguish among three broad categories of
JavaScript objects and two types of properties:
• A native object is an object or class of objects defined by the ECMAScript specification.
Arrays, functions, dates, and regular expressions (for example) are native
objects.
• A host object is an object defined by the host environment (such as a web browser)
within which the JavaScript interpreter is embedded. The HTMLElement objects
that represent the structure of a web page in client-side JavaScript are host objects.
Host objects may also be native objects, as when the host environment defines
methods that are normal JavaScript Function objects.
• A user-defined object is any object created by the execution of JavaScript code.
• An own property is a property defined directly on an object.
• An inherited property is a property defined by an object’s prototype object.
2.0.2.property attributes(3个)
property attributes:
• The writable attribute specifies whether the value of the property can be set.
• The enumerable attribute specifies whether the property name is returned by a
for/in loop.
• The configurable attribute specifies whether the property can be deleted and
whether its attributes can be altered.
2.0.3.object attributes(3个)
every object has three associated object attributes:
• An object’s prototype is a reference to another object from which properties are
inherited.
• An object’s class is a string that categorizes the type of an object.
• An object’s extensible flag specifies (in ECMAScript 5) whether new properties may
be added to the object.
2.1.属性的继承
注意这里使用了inherit函数来模拟
> // inherit() returns a newly created object that inherits properties from the undefined > // prototype object p. It uses the ECMAScript 5 function Object.create() if undefined > // it is defined, and otherwise falls back to an older technique. undefined > function inherit(p) { ... if (p == null) throw TypeError(); // p must be a non-null object ... if (Object.create) // If Object.create() is defined... ... return Object.create(p); // then just use it. ... var t = typeof p; // Otherwise do some more type checking ... if (t !== "object" && t !== "function") throw TypeError(); ... function f() {}; // Define a dummy constructor function. ... f.prototype = p; // Set its prototype property to p. ... return new f(); // Use f() to create an "heir" of p. ..} undefined > var o = {} // o inherits object methods from Object.prototype undefined > o.x = 1; // and has an own property x. 1 > var p = inherit(o); // p inherits properties from o and Object.prototype undefined > p.y = 2; // and has an own property y. 2 > var q = inherit(p); // q inherits properties from p, o, and Object.prototype undefined > q.z = 3; // and has an own property z. 3 > var s = q.toString(); // toString is inherited from Object.prototype undefined > q.x + q.y // => 3: x and y are inherited from o and p 3 > s '[object Object]' > q { z: 3 } > o.toString() '[object Object]' > o { x: 1 } > p { y: 2 } > o.x=11 11 > o { x: 11 } > q.x 11 > q.x+q.y 13 > q.x=111 <span style="color:#330033;"><span style="background-color: rgb(180, 100, 0);">//注意,这里其实是为q增加了一个新的属性x,他覆盖了原型里面继承来的属性x,所以这里设置了新的值,但是原型里面的x并未改变,o.x仍然是11</span></span> 111 > o.x 11 > q.x+q.y 113 >
在js中,只有在查询属性时才会体会到继承的存在,而设置属性则和继承无关,这是js的一个重要特性,该特性让程序员可以有选择地覆盖集成的属性。
有一个例外,如果o继承了属性x,继承来的属性x是具有setter方法的accessor属性,那么这时候将调用setter方法而不是给o创建一个属性x。这个setter方法操作只是针对o本身的属性,并不会修改原型链。
2.2.属性访问错误
var empty = {}; // An object with no properties var point = { x:0, y:0 }; // Two properties var point2 = { x:point.x, y:point.y+1 }; // More complex values var book = { "main title": "JavaScript", // Property names include spaces, 'sub-title': "The Definitive Guide", // and hyphens, so use string literals "for": "all audiences", // for is a reserved word, so quote author: { // The value of this property is firstname: "David", // itself an object. Note that surname: "Flanagan" // these property names are unquoted. } };
2.3.枚举属性
除了for in以外,我们还有其他方法去枚举属性
js实用工具库:
Example 6-2. Object utility functions that enumerate properties /* * Copy the enumerable properties of p to o, and return o. * If o and p have a property by the same name, o's property is overwritten. * This function does not handle getters and setters or copy attributes. */ function extend(o, p) { for(prop in p) { // For all props in p. o[prop] = p[prop]; // Add the property to o. } return o; } /* * Copy the enumerable properties of p to o, and return o. * If o and p have a property by the same name, o's property is left alone. * This function does not handle getters and setters or copy attributes. */ function merge(o, p) { for(prop in p) { // For all props in p. if (o.hasOwnProperty[prop]) continue; // Except those already in o. o[prop] = p[prop]; // Add the property to o. } return o; } /* * Remove properties from o if there is not a property with the same name in p. * Return o. */ function restrict(o, p) { for(prop in o) { // For all props in o if (!(prop in p)) delete o[prop]; // Delete if not in p } return o; } /* * For each property of p, delete the property with the same name from o. * Return o. */ function subtract(o,p) { for(prop in p) { // For all props in p delete o[prop]; // Delete from o (deleting a // nonexistent prop is harmless) } return o; } /* * Return a new object that holds the properties of both o and p. * If o and p have properties by the same name, the values from o are used. */ function union(o,p) { return extend(extend({},o), p); } /* * Return a new object that holds only the properties of o that also appear * in p. This is something like the intersection of o and p, but the values of * the properties in p are discarded */ function intersection(o,p) { return restrict(extend({}, o), p); } /* * Return an array that holds the names of the enumerable own properties of o. */ function keys(o) { if (typeof o !== "object") throw TypeError(); // Object argument required var result = []; // The array we will return for(var prop in o) { // For all enumerable properties if (o.hasOwnProperty(prop)) // If it is an own property result.push(prop); // add it to the array. } return result; // Return the array. }
hasOwnProperty是自有属性
Object.keys() //数组:[可枚举的自有属性的名称]
Object.getOwnPropertyNames()//数组:[自由属性的名称]
2.4.属性的特性
数据属性和存取器属性
数据属性的4个特性:value,writable,enumerable,configurable
存取器属性的4个特性:get,set,enumerable,configurable
属性描述符property descriptor
Object.getOwnPropertyDescriptor()可以获得某个对象特定属性的属性描述符
Object.defineProperty()可以设置属性的特性
新版本的extend方法:考虑了复制属性的特性,也考虑了复制存取器属性的getter和setter方法
/* * Add a nonenumerable extend() method to Object.prototype. * This method extends the object on which it is called by copying properties * from the object passed as its argument. All property attributes are * copied, not just the property value. All own properties (even non- * enumerable ones) of the argument object are copied unless a property * with the same name already exists in the target object. */ Object.defineProperty(Object.prototype, "extend", // Define Object.prototype.extend { writable: true, enumerable: false, // Make it nonenumerable configurable: true, value: function(o) { // Its value is this function // Get all own props, even nonenumerable ones var names = Object.getOwnPropertyNames(o); // Loop through them for(var i = 0; i < names.length; i++) { // Skip props already in this object if (names[i] in this) continue; // Get property description from o var desc = Object.getOwnPropertyDescriptor(o,names[i]); // Use it to create property on this Object.defineProperty(this, names[i], desc); } } });
2.5.对象的三个属性(object attribute)
prototype
class
extensible
2.5.1.prototype attribute(原型属性,很多时候简称为原型)
Object.getPrototyoeOf()
isPrototypeOf()用来检测一个对象是否是另外一个对象的原型
> var p = {x:1}; // Define a prototype object. undefined > var o = Object.create(p); // Create an object with that prototype. undefined > p.isPrototypeOf(o) // => true: o inherits from p true > Object.prototype.isPrototypeOf(o) // => true: p inherits from Object.prototype true > Object.isPrototypeOf(o) // => true: p inherits from Object.prototype false >
isPrototypeOf()函数实现的功能和instanceof运算符非常类似
2.5.2.class attribute(类属性)
function classof(o) { if (o === null) return "Null"; if (o === undefined) return "Undefined"; return Object.prototype.toString.call(o).slice(8,-1); }
上面使用了Function.call()方法,就可以保证使用的toString不是被重写的。
原始的toString()方法返回如下格式的信息:
[object class]
classof(null) // => "Null" classof(1) // => "Number" classof("") // => "String" classof(false) // => "Boolean" classof({}) // => "Object" classof([]) // => "Array" classof(/./) // => "Regexp" classof(new Date()) // => "Date" classof(window) // => "Window" (a client-side host object) function f() {}; // Define a custom constructor classof(new f()); // => "Object"
自定义类,没办法通过类属性来区分对象的类。
2.5.3.extensible 可扩展性
> var o = Object.seal(Object.create(Object.freeze({x:1}), ... {y: {value: 2, writable: true}})); undefined > o {} > o.x 1 > o.y 2 > Object.isSealed(o) true > Object.isFrozen(o) false > > Object.isExtensible(o) false >
Object有几个函数比较有用:
Object.isExtensible()
Object.preventExtensions()
Object.seal()
Object.isSealed()
Object.freeze()
Object.isFrozen()
2.6.序列化对象
JSON.stringify(o)
JSON.parse(s)
JSON:javascript object notation 对象表示法
JSON是序列化时候使用的数据交换格式
但是JSON的语法是js的一个子集,它并不能表示js里的所有值。
函数,RegExp,Error对象和undefined值不能序列化和还原。
而且只能序列化对象可枚举的自有属性。
2.7.对象方法
所有的js对象都从Object.prototype继承属性。这些继承属性主要是方法。
hasOwnProperty()
propertyIsEnumerable()
isPrototypeOf()
create()
getPrototypeOf()
toString()
toLocaleString()
toJSON()
valueOf()
toString,valueOf和toJSON是自定义类经常要重写的几个方法。