对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();

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

 
 

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();

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

原文地址:https://www.cnblogs.com/koleyang/p/5254723.html