2014-07-02 123 views
0

我遇到了一个闭包问题,我想。我只是做OOP JavaScript的新手(我本周开始......),但是我已经在这里或那里使用了JavaScript来处理小DOM操作,并且使用了很多次JQuery魔法。我正在寻找解决我的问题的方法,不涉及更改我的标准,因为我想尝试并最终学习正确的JavaScript。我的标准是,我希望解决方案能够保持我的封装和Java风格公开访问的私有变量。我的标准还需要解决方案,以便能够教我一些关于闭包的知识,而不必在[本页]重复示例:How do JavaScript closures work?Javascript闭包对象属性访问器

我已经在互联网上寻找解决方案,解决了我的问题和我一直在寻找的视频,我在学校学习的红色书籍,我有红色的网页和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.setName()thisthis.setName()做我想要的并且发现动物并且增加一个名字给我的驼鹿而不引起它的驼鹿弟兄们也被称为“moosey驼鹿mcDonkeybutt”或者什么......

我可以成功,然后在控制台中创建两个'Meese'或Mooses(如果你愿意并且每个都有自己的分隔值)。像...

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

而且当检查时m1的值不会与m2相同。这就是我期望从多年来使用的其他语言......但是,这是我感到困惑的地方,或者至少在我的电脑上炫耀,就像,“这是怎么回事?”

我想添加一些能力来衡量每只动物如何随着时间的推移而移动。所以我想,哎,为什么不趁这个时候使用真棒力量和对象字面来存储这些我班里面....像这样的简单....

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哈!到下一部分的时刻。如果你已经猜到我会错误的,你应该回答。 为什么地球上这会导致m1m2现在具有相同的共享值?它不是因为它公开宣布我已经尝试过私人范围,而且它只是让this更难找到正确的原型。

我已经试过这么多的版本的代码在这个块试图找出为什么我似乎无法存储我的立场作为一个简单的小对象文字与方便访问...我需要所有实例的驼鹿( )不能通过使用上面的setPosition()函数来改变彼此的位置....

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

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

+0

答复者,请跳过阅读前三段......这与问题完全无关。 – thefourtheye

+0

在分配给它的原型和其他东西后,看到* Moose *的函数声明是相当烦人的。如果代码是按照逻辑顺序编写的,那么理解它就容易多了。 – RobG

+0

@RobG是的,应该肯定会切换。 – John

回答

2

让我们一步一步来。

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

那么如何Moose对象得到position

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

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

我们如何解决此得到什么?

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

+0

好的答案。 OP,你可能会发现这个链接有助于解释原型继承http://javascriptissexy.com/javascript-prototype-in​​-plain-detailed-language/ – drjimmie1976

+0

我知道我可以把它放在驼鹿的构造函数中,但我只是觉得它看起来像来自java和c#的可怕代码。当它可以属于从继承创建的所有东西时重复该变量创建,就好像我重复的东西太多了。 – GoreDefex

+0

换句话说,即使对象生活在被孩子们使用的实例化父对象中,它们也不会被matrer传递。我想我不习惯如何JavaScript实例其对象,如动物。 – GoreDefex