Javascript Closures对象属性访问器

时间:2014-07-02 03:59:07

标签: javascript inheritance properties closures accessor

我认为闭包有问题。我真的很擅长OOP JavaScript(我本周开始......)但是我已经在这里或那里使用JavaScript进行小型DOM操作,并且JQuery魔术使用了很多次。我正在寻找一个解决我的问题的方法,不涉及改变我的标准,因为我想尝试并最终学习正确的JavaScript。我的标准是我希望解决方案能够维护我的封装和Java风格的公共访问私有变量。我的标准还需要解决方案,以便能够教我一些关于闭包的内容,而无需重复[thisPage]上的示例:How do JavaScript closures work?

我已经在互联网上搜索了我的问题解决方案和我一直在寻找的视频,我在校学习的书籍,我有红色的网页和S.O.我经历过的帖子还没有给我一个很好的答案,为什么会这样。那个或我真的无法掌握封闭或者这个问题是什么......

我有一个这样的课程:

var Animal = {
    $name: "Blank",
    $age: -1,
    setName: function(n) {this.name=n;},
    setAge: function(a) {this.age=a;}
};

然后我打电话给...

Moose.prototype = Object.create(Animal);
Moose.prototype.constructor = Moose;
function Moose(newName, newAge) {
    this.setName(newName);
    this.setAge(newAge);
}

this中的this.setName()做了我想要的事情并找到了动物,并为我的驼鹿添加了一个名字,而没有让它的驼鹿兄弟被称为" moosey moose mcDonkeybutt"什么......

我可以成功地在控制台中创建两个Meese'如果你愿意,或者每个人都有自己独立的价值观。像...

m1 = new Moose("MooseyMoose", 420);
m2 - new Moose("MooseMcTingles", 69);

在检查时,m1与m2的值不同。这是我多年来使用的其他语言所期望的......然而,这是我感到困惑的地方,或者至少瞪着我的电脑,例如,哇,"什么是douce?"

我想添加某种能力来衡量每只动物随时间的变化情况。所以我想,嘿,为什么不花时间利用对象文字的强大功能和简洁性将它存储在我的班级里....就像这样....

var Animal = {
    $name: "Blank",
    $age: -1,
    $position: {x:-1,y:-1},
    setName: function(n) {this.name=n;},
    setAge: function(a) {this.age=a;},
    getName: function() { return this.name; }
};

所以我在我的访问者中添加了一些额外的负载......

var Animal = {
    $name: "Blank",
    $age: -1,
    position: {x:-1,y:-1}, //I have tried $ and without
    setName: function(n) {this.name=n;},
    setAge: function(a) {this.age=a;},
    getName: function() { return this.name; },

    //New Accessor
    setPosition: function(newX, newY) {
        this.position.x = newX;
        this.position.y = newY;
    }
};

我确信经验丰富的程序员正在阅读这一点并且说......真是个白痴。问题是我没有阅读,搜索或找到答案让我的AHH HA!下一部分的时刻。如果你已经猜到我会有什么不对的话,你应该回答。 为什么这会导致m1m2现在在位置上拥有相同的共享值?这不是因为它公开声明我已尝试使用私有作用域它只会让this更难找到正确的原型。

我已经尝试过这个块的许多版本的代码试图弄清楚为什么我似乎无法将我的位置存储为一个简单的小对象文字,并且易于访问...我需要所有Moose实例()无法使用上面的setPosition()函数更改彼此的位置....

另外。我已经尝试将它全部转换为function对象而不是var对象,我也尝试删除了许多我知道不是this的组合。达到我需要的范围,但是没有运气。我还尝试删除使用.create()方法并切换到new关键字,但也没有运气。

编辑:对ppl的回复....就像我说我已经尝试过所有这一切,包括将getter setter方法添加到位置变量。它根本没有帮助它仍然有价值....

1 个答案:

答案 0 :(得分:2)

让我们一步一步来。

  

您是否在position构造函数中定义了名为Moose的成员?

没有

  

那么Moose的对象如何得到position

通过继承。由于Moose.prototype设置为Animal类型的对象,因此当您说m1.position时,JavaScript会在m1中搜索position,并在继承阶梯中向上移动在Moose.prototype对象中找到它。这种搜索对m1m2都很常见。因此,他们都在Animal中找到了相同的Moose.prototype对象。您可以像这样确认

console.log(m1.position === m2.position);
# true
  

我们如何解决这个问题?

简单。不要在Parent对象中定义子对象的成员变量。只需将position的定义移至Moose构造函数即可。现在,当JavaScript搜索m1.positionm2.position时,他们都会拥有自己的position副本: - )