目录
__proto__属性
__proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。目前,所有浏览器(包括 IE11)都部署了这个属性。该属性没有写入 ES6 的正文,而是写入了附录,原因是__proto__前后的双下划线,说明它本质上是一个内部属性,而不是一个正式的对外的 API, 只是由于浏览器广泛支持,才被加入了 ES6。标准明确规定,只有浏览器必须部署这个属性,其他运行环境不一定需要部署,而且新的代码最好认为这个属性是不存在的。
let objProto = {
name : "张三",
}
let obj = {
__proto__ : objProto,
}
console.log(obj.name) //张三
无论从语义的角度,还是从兼容性的角度,都不要使用这个属性,而是使用下面的 Object.setPrototypeOf()(写操作),Object.getPrototypeOf()(读操作),Object.create()(生成操作)代替。
let someObject = {
name : "wang",
}
let obj = Object.create(someObject);
console.log(obj.name); //wang
在Object上实现__proto__属性
const isObject = (value) => Object(value) === value;
Object.defineProperty(Object,"__proto__",{
get(){
let _thisObj = Object(this);
return Object.getPrototypeOf(_thisObj);
},
set(prpto){
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();
}
},
});
如果一个对象本身部署了__proto__属性,那么该属性的值就是这个对象的原型。
console.log(Object.getPrototypeOf({__proto__ : null})); //null
Object.setPrototypeOf()
Object.setPrototypeOf方法的作用与__proto__相同,用来设置一个对象的prototype对象,返回参数对象本身。它是 ES6 正式推荐的设置原型对象的方法。
const objPrototype = {
name : "abc",
age : 18,
}
const obj = Object.setPrototypeOf({},objPrototype);
console.log(obj.name,obj.age); //abc 18
该方法如果第一个参数不是对象,会自动转为对象。但是由于返回的还是第一个参数,所以这个操作不会产生任何效果。
console.log(Object.setPrototypeOf(1,{ a : 1})); //1
console.log(Object.setPrototypeOf(true,{ a : 1})) //true
console.log(Object.setPrototypeOf("abc",{a : 1})) //abc
由于undefined和null无法转为对象,所以第一个参数为undefined或者null的话,就会报错。
console.log(Object.setPrototypeOf(undefined,{})); //error
console.log(Object.setPrototypeOf(null,{})); //error
Object.getPrototypeOf()
该方法与Object.setprototypeOf()方法配套,用于读取一个对象的原型对象。
const objPrototype = {
name : "abc",
age : 18,
}
const obj = Object.setPrototypeOf({},objPrototype);
console.log(Object.getPrototypeOf(obj));
如果参数不是对象,会被转换为对象。
console.log(Object.getPrototypeOf(1));
console.log(Object.getPrototypeOf(true));
console.log(Object.getPrototypeOf("123"));
由于undefined和null不能转换为对象,所以会报错。
console.log(Object.getPrototypeOf(undefined)); //error
console.log(Object.getPrototypeOf(null)); //error