【问题标题】:How to obtain true de-referenced object instances in javascript如何在javascript中获取真正的取消引用对象实例
【发布时间】:2014-08-19 04:39:03
【问题描述】:

我试图更好地理解 JavaScript 中的面向对象模式。我特别喜欢 EmberJS 使用父类对象的 .extend 和 .create 实现其类的方式。

我尝试自己实现一个基本版本,但没有成功,我新实例化的对象引用了相同的对象。即如果我通过公共方法增加实例 a 中的私有计数器 var,然后分别对实例 b 执行相同操作,b 将反映两个增量。

我能够通过 Object.create(myClass) 实现取消引用的对象,但是这是不可取的,因为我想在内部实现这一点,并且也不依赖客户端对该本地方法的支持。

这是我所拥有的 jsbin:http://jsbin.com/zepaju/6/edit?js,console

感谢您的帮助!

【问题讨论】:

  • 旁白:我是candidate
  • 发现并修复,对手头的问题有任何想法吗?
  • @micahblu JavaScript 是 prototypical(基于原型);它实际上没有“类”,至少在传统意义上没有。
  • 另外,巴拉克奥巴马的名字中只有一个“r”...
  • JavaScript 没有 private 修饰符,有些人使用闭包来模拟它们牺牲原型。这里解释了 JavaScript 中的原型以及如何使用它。 stackoverflow.com/questions/16063394/…

标签: javascript oop ember.js


【解决方案1】:

这是一个相当大的主题,因为没有一种完美的方法可以让 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");

poll1poll2 不会相互影响,除非通过提供的方法,否则无法访问其中任何一个的投票计数。感谢您正在寻找一种更通用的方法,但这是您如何开始的一个示例。

【讨论】:

  • Douglas Crockford 的文章不是很好,它创建了一个 Parent 的实例来设置 Child 的原型,并且不通过 Parent.apply(this,arguments) 或类似的东西重新使用 Parent 构造函数。我看到他在“经典继承”中抱怨的确切事情,但他没有将其归咎于错误的代码,而是将其归咎于 JavaScript。然后它会修改 Function 并破坏封装,这对于担心由于封装而具有私有变量的人来说是一件奇怪且不一致的事情。
  • 仔细观察,那篇文章不是我想的那样——我很久以前读过它,似乎我把它和其他东西混淆了。我已经从原始答案中删除了链接,因为它在这里似乎没有启发性(而且非常臃肿和过时)。
  • 我在这里想要了解的是如何完成 Ember 通过类似于 App.MyObject = Ember.Object.create() 扩展和创建新对象/类实例的模式所完成的工作;它返回该对象的新实例,具有继承的原型链以及扩展原始类的任何其他对象。我将在这里走旧的时尚路线并深入研究他们的源代码:) 感谢您提供帮助的尝试
猜你喜欢
  • 2011-10-26
  • 2014-01-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 2015-01-08
  • 1970-01-01
相关资源
最近更新 更多