JavaScript中利用对象字面量创建对象原型属性的影响

众所周知,在 JavaScript 中,每个对象都有原型,在每个原型对象中都有一个 constructor 属性,指向对象本身。当我们在一个对象的原型上定义方法时,通常会这么做:

1
2
3
4
5
6
7
8
9
10
11
12
function Person(name, age) {
this.name = name;
this.age = age;
}

Person.prototype.sayHi = function () {
console.log("hello");
};

const p1 = new Person("Remilia", 23);

console.log(p1);


当我们打印该实例对象会发现,在其 prototype 中,除了有其定义的方法,还有指向自己的 contructor 属性。

如果我们使用对象字面量的形式去为一个原型对象增加属性的时候,会发生什么呢?

1
2
3
4
5
6
7
8
9
10
Person.prototype = {
sayHi: function () {
console.log("hello");
},
sayBye: function () {
console.log("goodbye");
},
};

console.log(Person.prototype);


现在整个 prototype 中只有两个定义的方法,没有 contructor 了,原因是:当我们以对象字面量的形式定义方法后,js 默认会将整个原型对象重新赋值,因此这里的 prototype 被新的对象字面量赋值从而丢失了能指向自己对象的 contructor。

如果我们既想以对象字面量的形式定义原型对象,又想使其与原本的对象关联起来。那么就需要在对象字面量中自己手动定义 constructor 方法并且与原有的对象关联即可。

1
2
3
4
5
6
7
8
9
10
11
Person.prototype = {
constructor: Person,
sayHi: function () {
console.log("hello");
},
sayBye: function () {
console.log("goodbye");
},
};

console.log(Person.prototype);

总结

以对象字面量的形式定义对象的原型属性在实际开发过程中相对来说是比较普遍的,印象定义起来比较方便也很直观,因此这里会存在一个隐形的小坑,报错时很大可能不容易发现。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!