对js原型对象的拓展和原型对象的重指向的区别的研究

我写了如下两段代码:

function Person(){} var p1 = new Person(); Person.prototype = { constructor: Person, name: "cxc", age: 20, sayName: function(){ console.log(this.name); } }; p1.sayName(); 

这一段的运行结果是:Uncaught TypeError: undefined is not a function
然后我又把它改写为下面的代码:

function Person(){} Person.prototype = { constructor: Person, name: "cxc", age: 20, sayName: function(){ console.log(this.name); } }; var p1 = new Person(); p1.sayName(); 

运行结果却是没问题的,为什么会这样呢。
原型不是具有动态性吗,在它上面所做的任何修改不是都会反映到实例上吗。所以我就有些想不明白了,烦劳哪位大神能给解释一下。在此先行谢过了。

  • 2014年05月18日提问
  • 评论
 
 

4 个回答

 

3

 
采纳

让我来给你解释一下吧。
看看下面这段代码

function Person(){} var proto1 = Person.prototype; var p1 = new Person(); Person.prototype = { constructor: Person, name: "cxc", age: 20, sayName: function(){ console.log(this.name); } }; console.log(Person.prototype.isPrototypeOf(p1)); //输出false console.log(proto1.isPrototypeOf(p1)); //输出true 

MDN Reference: Object.prototype.isPrototypeOf()
The isPrototypeOf() method tests for an object in another object's prototype chain.

意思就是:Object.isPrototypeOf(obj)可以用来检测该原型是否处于obj对象的原型链上。

在上面这段代码中,首先我将一开始Person.prototype的引用指向proto1
最后我重新检验发现,Person.prototype已经不是p1的原型了,而proto1还是p1的原型。

其实罪魁祸首就是Person.prototype = {...}这句话,因为它声明了一个新的对象,让Person.prototype指向它。

要实现题主所需要的动态增加属性的功能可以这么写:

function Person(){} var p1 = new Person(); Person.prototype.name = 'hi'; Person.prototype.sayName = function(){ console.log(this.name); } p1.sayName(); 

这样做就不是重新声明一个原型对象,而是对原来的原型对象进行扩展

你可能感兴趣的:(对js原型对象的拓展和原型对象的重指向的区别的研究)