function Person(name, age) {} // Person构造函数是个空函数,将默认值都放在原型对象中
Person.prototype.name
= name
Person.prototype.age = age
Person.prototype.sayHi = function() {
console.log(`hi, ${this.name
}`)
}
const p1 = new Person(‘xiaoming’, 20)
/*
实例对象的内部指针指向的是构造函数的原型对象
构造函数的prototype属性指向的也是这个原型对象
实例对象和构造函数之间没有直接的联系
*/
console.log(p1.__proto__ === Person.prototype) //true
console.log(Person.prototype.constructor)
/*
ƒ Person(name, age) {
this.name
= name
this.age = age
this.sayHi = function() {
console.log(`hi, ${this.name
}`)
}
构造函数的原型对象中的constructor指向的是构造函数
}
*/
// 尝试重写Person构造函数的原型对象
Person.prototype = {
name: ‘alice’,
age: 12,
sayLove: function() {
console.log(`i love ${this.name
}`)
}
}
console.log(Person.prototype.constructor) // ƒ Object() { [native code] }
重写了 prototype 之后发现它的constructor不再指向 Person,而是指向了Object构造函数
why ?
明确一点,在调用构造函数的时候,会为生成的新的实例对象添加一个指针指向构造函数的原型对象
那么在重写prototype的时候我们用对象字面量的方式创建了一个新的对象,而用这种方式创建就相当于调用了Object构造函数
不信可以试试
const o1 = {}
const o2 = new Object()
console.log(o1.__proto__ === o2.__proto__) // true
此时,在调用了Object构造函数创建一个新对象,并将这个新对象作为 Person 的 prototype 之后,
发现这个原型对象里面少了一个constructor属性;
当在一个实例对象中找不到该属性时,就会去这个实例对象的构造函数的原型对象中寻找,
这个原型对象的构造函数是 Object,所以就会去 Object构造函数的原型对象中寻找,
而我们前面说了,构造函数的原型对象中的constructor指向的是构造函数,
所以Object的原型对象中的constructor指向的还是Object,
那么如何避免这种情况呢?
如果constructor真的很重要,那么在重写原型对象的时候可以在对象中加上constructor属性,
这样的话就不会去新对象的原型对象中查找constructor属性了
Person.prototype = {
constructor: Person, // 注意这个值不是字符串
name: ‘alice’,
age: 12,
sayLove: function() {
console.log(`i love ${this.name
}`)
}
}
console.log(Person.prototype.constructor)
/*
ƒ Person(name, age) {
this.name
= name
this.age = age
this.sayHi = function() {
console.log(`hi, ${this.name
}`)
}
}
*/
转载请注明:XAMPP中文组官网 » 重写原型对象