【问题标题】:Privacy in JavaScriptJavaScript 中的隐私
【发布时间】:2016-06-15 12:44:42
【问题描述】:

函数作用域提供 JavaScript 中唯一的隐私。

所以规范:

function Ctor(dep1, dep2) {
  this._dep1 = dep1;
  this._dep2 = dep2;
}

Ctor.prototype.foo = function() {
  // use this._dep1/2...
}

...问题在于它没有为注入的依赖项提供封装。

提供真正封装的替代方案(尽管foo 的位置略有不同)可能是:

function factory(dep1, dep2) {
  return {
    foo: partial(foo, dep1, dep2), // or use bind (partial could be a library fn for partial application)
  };
}

function foo(dep1, dep2) {
  // use dep1/2
}

但我很少看到这种模式。是否有充分的理由不使用后者?

【问题讨论】:

  • 在某种程度上,对 Symbol 属性的支持会让事情变得更好,因为可以创建保证不会与其他键冲突的属性键。但是,它们仍然不是完全“私有的”。
  • 投票赞成 - 为什么?!

标签: javascript partial-application


【解决方案1】:

您已经说明了第二种模式的优点。缺点是:

  • 您必须按可见性对方法进行分组(即使私有方法与公共方法密切相关,但与其他私有方法几乎没有关系),或者在对象字面量中重复所有公共方法(这不会与 jsdoc 一起工作)。

  • 代码为类的每个实例引入了一个单独的函数对象,这会牺牲一些性能(这通常无关紧要,但有时可能)

  • 与许多编程语言中的私有修饰符不同,这种封装不能被规避,即使被误用并且我真的知道我在做什么(从历史上看,JavaScript 一直是一个可以进行任何事情的环境,许多人将其成功归因于这种可扩展性)

【讨论】:

  • “代码为你的类的每个实例引入了一个单独的函数对象”——即使代码直接使用bind,例如foo: foo.bind(null, dep1, dep2)?
  • 是的,我刚刚在 Chrome 中测试过:foo.bind(null, 1, 2) === foo.bind(null, 1, 2) 返回false
  • 啊,是的,你是对的。感谢您的确认。还有developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
【解决方案2】:

简单:为什么?

“隐私”被严重高估了。它不会对任何真正想要它的人隐藏任何东西。拥有“受保护”或“私有”成员纯粹是为了程序员的利益,特别是表明应该如何使用特定成员(this 这里是公共 API,this 不是这样,除非您知道它的作用,否则请不要触摸它)。就这样。像开始下划线这样的命名约定就足以实现它。如果成员名称以下划线开头,请不要触摸它,除非您知道自己在做什么。

没有必要再向后弯腰。

【讨论】:

  • 回答您的问题:“因为使用_foo,在共享代码库中工作时,您不能确信它没有被使用,因为名称只是一个名称”。对后者的信心显着增加,改进了代码的非功能方面。
  • 如果你对你的同事没有信心,让私人成员更加私密对你没有帮助。这是程序员之间的沟通和/或审查问题,而不是要解决的技术问题。与访问私有成员相比,不受信任的程序员能够搞砸的事情还有很多。
  • 软件开发存在很多问题。你举几个。这是否意味着我们不应该尝试减轻这些问题带来的风险?
  • 是的,我们应该这样做,但同样:并非所有解决方案都具有技术性质。在 Javascript 中使成员“真正”私有需要相当多的向后弯曲,这通常会导致代码不太清晰。您的第一个代码示例:每个人都得到它;你的第二个:......呃......这是做什么的?如果问题在于团队成员不尊重他人的隐私,请教育您的团队成员,不要混淆您的代码。
  • 我们是如何解决版本控制问题的?使用 Javascript 中的复杂注释技术?否:通过外部手段。你如何解决一个团队践踏彼此代码的问题?通过与相关人员交谈,教育他们如何一起工作。
猜你喜欢
  • 1970-01-01
  • 2010-11-29
  • 1970-01-01
  • 2012-01-19
  • 2012-12-03
  • 2013-08-18
  • 2011-02-25
  • 1970-01-01
  • 2011-11-19
相关资源
最近更新 更多