重写原型对象的一些问题

2018-08-16  本文已影响0人  sprittee

首先我们创建对象Scholar,并且示例化对象,然后重写原型

function Scholar() {
}
var scholar=new Scholar();
Scholar.prototype = {
    name: "Aron",
    age: "22",
    job: "hacker",
    sayName: function() {
        alert(this.name);
    }
};
scholar.sayName();//TypeError:scholar.sayName is not a function

运行时我们会发现错误

TypeError:scholar.sayName is not a function

为什么会这样呢?

这就牵涉到了原型对象和实例对象的关系,在上述对象中,如果我要在scholar对象上调用sayName()方法,就会先判断scholar对象的属性中有没有sayName这个属性,如果有,就直接调用,没有的话就在scholar的原型对象prototype中寻找,这个原型对象,它是一个类固有的属性,跟constructor类似这里需要注意的是,用构造函数创建的实例,会自动包含一个叫做[[prototype]],[[prototype]]是一个指针,[[prototype]] 指向一个Object Prototype,Object Prototype是一个特殊的实例,在上文中,我们可以通过以下代码直接访问原型属性。

alert(Scholar.prototype.name);//Aron

而当scholar没有sayName属性时,会通过[[prototype]]指针找到Scholar Prototype表,在这种添加原型属性的情况下,sayName是可以被找到的。

Scholar.prototype.name="Aron";
Scholar.prototype.sayName=function(){
    alert(this.name);
};
Scholar.prototype.sayName();//Aron
scholar.sayName();//Aron

但是如果通过重写整个prototype来”修改Prototype",是不可以通过scholar上的[[prototype]]找到sayName的,因为重写整个prototype会重新创建一个新的Scholar Prototype原型对象,已创建scholar上的[[prototype]]指针还是指向了旧的Scholar Prototype原型对象,自然是找不到sayName属性了。

因此,要想重写prototype,还能让对象的[[prototype]]指针指向新的Scholar Prototype原型对象,最简单的办法就是重写完原型对象再进行实例化操作了。

function Scholar() {
}
Scholar.prototype = {
    name: "Aron",
    age: "22",
    job: "hacker",
    sayName: function() {
        alert(this.name);
    }
};
var scholar=new Scholar();//实例化scholar在重写原型之后
scholar.sayName();//Aron
上一篇 下一篇

猜你喜欢

热点阅读