我有一个JavaScript对象,我想扩展它。问题是它的变量从一个范围变异到另一个范围。
首先,我创建了一个Mammal原型,并且他有一个名字,这个名字可以用whoAmI
函数打印
var Mammal = ( function () {
var whoAmI = function () {
console.log("I am " + this.name);
};
return {
name : "mammal",
whoAmI : whoAmI
};
})();
然后,我创造了一只狗,它也有一个名字。它的名称可以直接从whoAmI
或state
函数打印。
var Dog = ( function (mammal) {
mammal.name = "dog";
mammal.state = function () {
mammal.whoAmI();
console.log("I am happy");
};
return mammal;
})(Object.create(Mammal));
但是当我想创建一个Dog实例并从外部设置他的名字时,似乎有两个name
变量:一个在Dog中,另一个在新创建的变量中shipo
var shipo = Object.create(Dog);
shipo.name = "Shipo"
shipo.state(); // it's name is dog
shipo.whoAmI(); // it's name is Shipo
// mutation? :(
我可以通过在Mammal定义上为name
变量实现getter和setter函数来解决这个问题......但是我讨厌使用getter和setter,如果变量可以公开,我的代码会更短在没有这种丑陋功能的情况下设定并获得......
getter和setter是防止这种突变的唯一方法吗?
答案 0 :(得分:3)
在这种情况下,修复非常简单:只需调用this.whoAmI()
而不是mammal.whoAmI()
来访问当前对象而不是其原型属性:
var Dog = ( function (mammal) {
mammal.name = "dog";
mammal.state = function () {
this.whoAmI();
console.log("I am happy");
};
return mammal;
})(Object.create(Mammal));
会给出预期的结果:
我是石浦 我很高兴 我是Shipo
以下是继承链的简化方案:
+--------------+ +--------------+
| Mammal | +--> | Dog |
+--------------+ | +--------------+
| __proto__ |--+ | __proto__ |
+--------------+ +--------------+
| name: mammal | | name: dog |
| whoAmI() | | state() |
+--------------+ +--------------+
从此表中可以很容易地看到,如果Dog
调用state
方法的实例,您希望在当前this
对象上调用它,以便它可以选择向上this.name
,而不是mammal.name
。