1.通过继承(Object.create())创建对象的好处?
防止函数库无意间或恶意的修改那些不受你控制的对象。不是将对象直接传入到函数,而是将它的继承对象传入,
函数读取到的实际上是继承来的值,如果给继承对象赋值,则影响到的是继承的对象,而不是当前对象本身。
1 var o = {}; 2 o.x = 1; 3 var p = inherit(o); 4 p.y = 2; 5 var q = inherit(p); 6 q.z = 3; 7 var s = q.toString(); //3 x为o的属性,y为p的属性,z才是q的属性 8 q.x + q.y 9 10 function inherit(p) { 11 if(p == null) throw TypeError(); 12 if(Object.create) return Object.create(p); 13 var t = typeof p; 14 if(t !== "objcet" && t !== "function") throw TypeError(); 15 function f() {}; 16 f.prototype = p; 17 return new f(); 18 19 }
2.如何防止查询属性报错
1 var len = book.subtitle.length; //null 和 undefined都没有属性,报错 2 //冗余但很易懂的方法 3 var len = undifined; 4 if(book) { 5 if(book.subtitle) len = book.subtitle.length; 6 } 7 //一种更简练的常用方法。 8 var len = book && book.subtitle && book.subtitle.length;
3.检测属性的三种方法
1)in
var o = {x: 1};
"x" in o; //true
2)hasOwnProperty()
o.hasOwnproperty("x") //true 有一个自有属性,继承而来的不算
3)propertyIsEnumerable() //hasOwnProperty的增强版
o.hasOwnProperty("x") //true 有一个自有属性且是可枚举的
4.存取器属性
1 var p = { //存取器属性,注意写法,函数后是逗号分隔,get、set与函数名之间没有冒号 2 x : 1, 3 y : 2, 4 5 get r() {return Math.sqrt(this.x * this.x + this.y * this.y); }, 6 set r(newValue) { 7 var oldValue = Math.sqrt(this.x * this.x + this.y * this.y); 8 var ratio = newValue / oldValue; 9 this.x *= ratio; 10 this.y *= ratio; 11 }, 12 //只读存取器属性,只有get方法 13 get theta() { return Math.atan2(this.y, this.x); }, 14 }
5.属性的特性
一般的属性都有四个特性:value, writable, enumerable, configurable
Object.getOwnPropertyDescriptor({x:1}, "x"); //1, true, true, true
该方法可以获得特定属性的属性描述符。
Object.getOwnPropertyDescriptor(random, "obct"); //get:/*func*/, set:undefined, enumerable:true, configurable:true;
Object.defineProperty( Object, "Object.value", { value:arg0, writable: arg1, enumerable: arg2, configurable: arg3 })
可以设置属性的特性。同时创建或修改多个属性
var p = Object.defineProperties({}, { x: { value: 1, writable: true, enumerable: true, configurable: true }, y: { value: 1, writable: true, enumerable: true, configurable: true }, r: { get: function () { return Math.sqrt(this.x * this.x + this.y * this.y); }, enumerable: true, configurable: true } })