如何在javascript中获得真正的取消引用对象实例
我试图更好地理解JavaScript中的面向对象模式。我特别喜欢EmberJS使用.extend和.create从父类对象实现类的方式 我曾尝试自己实现一个基本版本,但没有成功,我新实例化的对象引用了同一个对象。也就是说,如果我通过公共方法增加实例a中的私有计数器变量,然后分别对实例b执行相同的操作,那么实例b将反映这两个增量 我能够通过object.create(myClass)实现一个取消引用的对象,但是这是不可取的,因为我希望在内部实现这一点,也不依赖客户端对该本地方法的支持 这是我得到的一个jsbin:如何在javascript中获得真正的取消引用对象实例,javascript,oop,ember.js,Javascript,Oop,Ember.js,我试图更好地理解JavaScript中的面向对象模式。我特别喜欢EmberJS使用.extend和.create从父类对象实现类的方式 我曾尝试自己实现一个基本版本,但没有成功,我新实例化的对象引用了同一个对象。也就是说,如果我通过公共方法增加实例a中的私有计数器变量,然后分别对实例b执行相同的操作,那么实例b将反映这两个增量 我能够通过object.create(myClass)实现一个取消引用的对象,但是这是不可取的,因为我希望在内部实现这一点,也不依赖客户端对该本地方法的支持 这是我得到的
谢谢你的帮助 这是一个相当大的主题,因为没有一种完美的方法让JavaScript像Java一样工作——你总是需要发明一些新的编码习惯,不同的人有不同的偏好 查看链接的代码,很难确定您的目标是什么,但问题似乎是您将对象的原型视为一个“类”,它被复制到每个“实例”(如Java中)——事实并非如此 您的
create()
函数通过执行Object.create(Poll)
创建每个“实例”,这将创建一个新对象,并将Poll对象作为其原型。当您引用结果对象的属性,并且这些属性没有直接在对象上定义时,您得到的是对单个Poll
对象的属性的引用
事实上,您已经将Poll对象的内部变量密封在一个闭包中,这与此没有任何区别;闭包变量对外隐藏,但是Poll
对象的方法可以访问它们,并且这些方法在所有“实例”之间共享
如果您想要一个函数,该函数使用一组特定的方法吐出对象,并将其内部数据隐藏在闭包中,则该函数可能如下所示:
function Poll(challenger,incumbent) {
var challengerVotes=0;
var incumbentVotes=0;
return {
voteForChallenger: function() {challengerVotes++},
voteForIncumbent: function() {incumbentVotes++},
winner: function() {return challengerVotes>incumbentVotes ? challenger : incumbent}
}
}
var poll1 = Poll("Edward","Jacob");
var poll2 = Poll("Vanilla","Stilton");
poll1
和poll2
不会相互影响,除非通过提供的方法,否则无法访问其中任何一个的投票计数。我很感激您正在寻找一种更通用的方法,但这是一个如何开始的示例。旁白:它是。明白了,已经修复,对手头的问题有什么想法吗?@micahblu JavaScript is(基于原型);它没有真正的“类”,至少在传统意义上没有。而且,巴拉克·奥巴马的名字中只有一个“r”…JavaScript没有私有修饰符,有些人使用闭包来模拟原型。这里解释了JavaScript中的原型以及如何使用它。Douglas Crockford的文章不是很好,它创建了一个父实例来设置子实例的原型,并且没有通过执行Parent.apply(这个,参数)
或类似操作来重用父构造函数。我看到他在“经典继承”中抱怨的正是这些事情,但他没有将其归咎于错误的代码,而是将其归咎于JavaScript。然后它修改了函数并破坏了封装,对于那些因为封装而关注私有变量的人来说,这是一件奇怪且不一致的事情。仔细观察,那篇文章并不是我所想的——我很久以前读过它,似乎把它与其他东西混淆了。我已经删除了原始答案中的链接,因为它在这里似乎没有什么启发性(而且非常臃肿和过时)。我在这里的目的是了解如何通过类似于App.MyObject=Ember.object.create()的东西实现Ember扩展和创建新对象/类实例的模式;它返回该对象的新实例,以及继承的原型链以及扩展原始类的任何其他对象。我要走老路,深入研究他们的源代码:)感谢您的帮助