1、对象概述
1.1、对象常见的用法:
create 、set 、Query 、delete 、test、enumerate
1.2、对象的属性特性:
可写、可枚举、可配置
1.3、每个对象的对象特性:
原型、对象的类、对象的可扩展性
1.4、对象和属性分类:
内置对象、宿主对象、自定义对象、自由属性、继承属性
2、创建对象
2.1、对象直接量
2.2、通过new创建对象
2.3、原型
2.4、Object.create()
第一个参数:这个对象的原型
第二个参数:可选、对对象的属性进行进一步描述
var o1 = Object.create({x:1, y:2}); // o1 inherits properties x and y. var o2 = Object.create(null); // o2 inherits no props or methods. var o3 = Object.create(Object.prototype); // o3 is like {} or new Object().
通用的inherit()函数,兼容版本(但是并不能完全替代create如不能接受第二参数)
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. }
3、属性的查询和设置
3.1、作为关联数组的对象
javascript对象都是关联数组,点访问和括号访问的差异
3.2、继承
3.3、属性访问错误
var len = book && book.subtitle && book.subtitle.length;
这段代码的作用:避免属性访问错误的方法
3.4下面的情形给对象o设置属性p会失败:
1、o中的属性p是只读的
2、o的属性p时继承的,且是只读的:不能通过自有属性覆盖只读属性的继承属性
3、o中不存在自有属性且o的可扩展性为false
4、删除属性:
4.1 delete只能删除自有属性,不能删除继承属性;
a = {p:{x:1}}; b = a.p; delete a.p;
note: b.p的值仍然是1;所以在销毁某个对象的时候,要遍历属性中的属性,一次删除
delete Object.prototype;//false 不能删除不可配置属性 var x = 1; delete this.x; //不能删除 function f() {} delete this.f; //不能删除全局函数 this.u = 1; delete u; //true
5、检测属性
in
!==undefined
hasOenpreperty()
propertyIsEnumerable()
6、 枚举属性:
6.1用于枚举属性的对象工具函数:
/**********合并p和o的可枚举属性,如果同名,覆盖o的属性,并返回o*/ function extend(o, p) { for (prop in p) { o[prop] = p[prop]; } return o; } function merge(o, p) { for (prop in p) { if (o.hasOwnProperty[prop]) continue; o[prop] = p[prop]; } return o; } function restrict(o, p) { for (prop in o) { if (!(prop in p)) delete o[prop]; return o; } } function subtract(o, p) { for (prop in p) { delete o[prop]; } return o; } function union(o, p) { return extend(extend({}, o), p); } function intersection(o, p) { return restrict(extend({}, o), p); } function keys(o) { if (typeof o !== "object") throw TypeError(); var result = []; for (var prop in o) { if (o.hasOwnProperty(prop)) result.push(prop); } return result; }
6.2 Es5 中的Object.keys():返回一个数组,这个数组由对象中的可以枚举的自由属性的名称组成
ES5中的Object.getOwnProperty Names():返回所有自由属性的名称,而不仅仅是可枚举属性
7、getter和setter: 存储器属性
ES5中的属性值可以用一个或两个方法函数取代
数据属性与存储器属性的不同:
例子:
var o = { // An ordinary data property data_prop: value, // An accessor property defined as a pair of functions get accessor_prop() { /* function body here */ }, set accessor_prop(value) { /* function body here */ } }; var p = { x: 1.0, y: 1.0, get r() { return Math.sqrt(this.x * this.x + this.y * this.y); }, set r(newvalue) { var oldvalue = Math.sqrt(this.x * this.x + this.y * this.y); var ratio = newvalue / oldvalue; this.x *= ratio; this.y *= ratio; }, get theta() { return Math.atan2(this.y, this.x); } }
这个对象产生一个严格的序列号:
var serialnum = { $n: 0, get next() { return this.$n++; }, set next(n) { if (n >= this.$n) this.$n = n; else throw "serial number can only be set to a larger value"; } };
random的一个神奇的属性:不固定,而是一个随机数
var random = { get octet() { return Math.floor(Math.random()*256); }, get uint16() { return Math.floor(Math.random()*65536); }, get int16() { return Math.floor(Math.random()*65536)-32768; } };
8、属性的特性
数据属性:值属性、可写性、可枚举性、可配置性
存储器属性:get/set/configurable/enumerable,它并没有值属性
设置属性特性的方法:
-
Object.getOwnPropertyDescriptor():
-
Object.defineProperties
设置属性特性的方法注意的规则: 详细见书中
重写extend工具函数:
Object.defineProperty(Object.prototype, "extend", { writable: true, enumerable: false, configurable: true, value: function (o) { var names = Object.getOwnPropertyNames(o); // Loop through them for (var i = 0; i < names.length; i++) { if (names[i] in this) continue; var desc = Object.getOwnPropertyDescriptor(o, names[i]); Object.defineProperty(this, names[i], desc); } } });
getter和setter的老式API:
__lookupGetter__() __lookupSetter__() __defineGetter__() defineSetter__()
9、对象的三个属性:
原型属性(判断原型):
Object.getprototypeof()
o.constructor.prototype
isPrototypeOf()
instanceof
类属性:注意通过对象直接量和Object.create创建的对象和自定义构造函数创建的对象的类属性是Object
function classof(o) { if (o === null) return "Null"; if (o === undefined) return "Undefined"; return Object.prototype.toString.call(o).slice(8,-1); }
如:
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"
可扩展性:
Object.isExtensible()
Object.preventExtensions().
Object.seal(); 将所有的对象设置不能扩展而且对象的所有自有属性设置不可删除和配置,不过他已有的可写属性仍然可以设置
Object.isSealed();
Object.freeze();更严格,自有的所有数据属性设置为只读,但是存储器属性不受影响
Object.isFrozen()
10、系列化对象,对象
11、对象方法:
hasOenproperty();
propertyIsEnumerable();
isPrototypeOf();
object.create()
object.getprototypeof()
toString()
toLocaleString();
toJson();
valueOf();