class Person {
constructor() {
this.name = 'xiaocai'
}
}
class Child {}
p = new Person
c = new Child
console.log(p.name) // xiaocai
console.log(c.name) // undefined
console.log(c._proto_) // class Child
Object.getPrototypeOf(c) //constructor:class Child
// getPrototypeOf 就是利用的 _proto_
Object.setPrototypeOf(c, p)
Object.getPrototypeOf(c).constructor === Person // true
通过上面可以发现,setPrototypeOf把c对象的原型设置成了p的原型。
getPrototypeOf和setPrototypOf
既然getPrototypeOf可以获取到原型对象,为啥还要引入spuer呢。我们先看一个例子。
let person = {
getGreeting() {
return "Hello";
}
};
let dog = {
getGreeting() {
return "Woof";
}
};
let friend = {
getGreeting() {
return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!";
}
};
// set prototype to person
Object.setPrototypeOf(friend, person);
console.log(friend.getGreeting()); // "Hello, hi!"
console.log(Object.getPrototypeOf(friend) === person); // true
// set prototype to dog
Object.setPrototypeOf(friend, dog);
console.log(friend.getGreeting()); // "Woof, hi!"
console.log(Object.getPrototypeOf(friend) === dog); // true
⚠️碰到的理解误区,call只是改变上下文环境,不是改变调用函数主体。文末解释。
可以发现上面这个是可以实现对应的方法调用,但是试试其他的情况。
let person = {
getGreeting() {
return "Hello";
}
};
// prototype is person
let friend = {
getGreeting() {
return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!";
}
};
Object.setPrototypeOf(friend, person);
// prototype is friend
let relative = Object.create(friend);
console.log(person.getGreeting()); // "Hello"
console.log(friend.getGreeting()); // "Hello, hi!"
console.log(relative.getGreeting()); // error!