( 1 )proto 属性
proto属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前,所有浏览器(包括 IE11 )都部署了这个属性。
1 2 3 4 5 6 7 8
| // es6 的写法 var obj = { method: function() { ... } }; obj.__proto__ = someOtherObj; // es5 的写法 var obj = Object.create(someOtherObj); obj.method = function() { ... };
|
该属性没有写入 ES6 的正文,而是写入了附录,原因是proto前后的双下划线,说明它本质上是一个内部属性,而不是一个正式的对外的 API ,只是由于浏览器广泛支持,才被加入了 ES6 。标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。因此,无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用下面的Object.setPrototypeOf()(写操作)、Object.getPrototypeOf()(读操作)、Object.create()(生成操作)代替。
在实现上,proto调用的是Object.prototype.proto,具体实现如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| Object.defineProperty(Object.prototype, '__proto__', { get() { let _thisObj = Object(this); return Object.getPrototypeOf(_thisObj); }, set(proto) { if (this === undefined || this === null) { throw new TypeError(); } if (!isObject(this)) { return undefined; } if (!isObject(proto)) { return undefined; } let status = Reflect.setPrototypeOf(this, proto); if (!status) { throw new TypeError(); } }, }); function isObject(value) { return Object(value) === value; }
|
如果一个对象本身部署了proto属性,则该属性的值就是对象的原型。
1 2
| Object.getPrototypeOf({ __proto__: null }) // null
|
( 2 ) Object.setPrototypeOf()
Object.setPrototypeOf方法的作用与proto相同,用来设置一个对象的prototype对象。它是 ES6 正式推荐的设置原型对象的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| // 格式 Object.setPrototypeOf(object, prototype) // 用法 var o = Object.setPrototypeOf({}, null); //该方法等同于下面的函数。 function (obj, proto) { obj.__proto__ = proto; return obj; } //下面是一个例子。 let proto = {}; let obj = { x: 10 }; Object.setPrototypeOf(obj, proto); proto.y = 20; proto.z = 40; obj.x // 10 obj.y // 20 obj.z // 40
|
上面代码将 proto 对象设为 obj 对象的原型,所以从 obj 对象可以读取 proto 对象的属性。
( 3 ) Object.getPrototypeOf()
该方法与 setPrototypeOf 方法配套,用于读取一个对象的 prototype 对象。
1 2 3 4 5 6 7 8 9 10
| Object.getPrototypeOf(obj); //下面是一个例子。 function Rectangle() { } var rec = new Rectangle(); Object.getPrototypeOf(rec) === Rectangle.prototype // true Object.setPrototypeOf(rec, Object.prototype); Object.getPrototypeOf(rec) === Rectangle.prototype // false
|