Javascript getter和setter是避免原型突变的唯一方法吗?

Javascript getter和setter是避免原型突变的唯一方法吗?,javascript,Javascript,我有一个JavaScript对象,我想扩展它。问题是它的变量从一个作用域变异到另一个作用域 首先,我创建了一个哺乳动物原型,他有一个名字,这个名字可以用whoAmI函数打印出来 var Mammal = ( function () { var whoAmI = function () { console.log("I am " + this.name); }; return { name : "mammal", whoA

我有一个JavaScript对象,我想扩展它。问题是它的变量从一个作用域变异到另一个作用域

首先,我创建了一个哺乳动物原型,他有一个名字,这个名字可以用
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? :(
我可以通过在哺乳动物定义上为
name
变量实现getter和setter函数来解决这个问题。。。但我讨厌使用getter和setter,如果变量可以公开设置并在没有这些丑陋函数的情况下获取,我的代码就会更短


getter和setter是防止这种突变的唯一方法吗?

解决方法非常简单:只需调用
this.whoAmI()
而不是
哺乳动物.whoAmI()
来访问当前对象而不是其原型属性:

var Dog = ( function (mammal) {
    mammal.name = "dog";
    mammal.state = function () {
        this.whoAmI();
        console.log("I am happy");
    };
    return mammal;
})(Object.create(Mammal));
将给出预期结果:

我是Shipo
我很高兴
我是Shipo

以下是继承链的简化方案:

+--------------+       +--------------+   
| Mammal       |  +--> | Dog          |
+--------------+  |    +--------------+
| __proto__    |--+    | __proto__    |
+--------------+       +--------------+
| name: mammal |       | name: dog    |
| whoAmI()     |       | state()      |
+--------------+       +--------------+

从这个表中很容易看出,如果
Dog
的一个实例调用
state
方法,您希望它在当前
this
对象上被调用,这样它就可以拾取
this.name
,而不是
哺乳动物.name

,我担心这个解决方案不允许我扩展Dog,因为
this.whoAmI
,会导致名称成为狗的名称,所以我做了这个测试:,它工作得非常完美!非常感谢:D