Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Coffeescript 调用私有方法的更好方法_Coffeescript - Fatal编程技术网

Coffeescript 调用私有方法的更好方法

Coffeescript 调用私有方法的更好方法,coffeescript,Coffeescript,我正在使用CoffeeScript创建一个类并构建一个私有方法,但我的代码感觉很笨拙 在下面的例子中,首先我用=定义方法,然后我被迫对要使用的部分使用call方法。但这似乎是一个笨拙的解决办法,所以我想知道是否有一个更干净的解决方案 class Human constructor: (@name, @height, @weight) -> _realWeight = -> @weight answerWeight: -> console.log(

我正在使用CoffeeScript创建一个类并构建一个私有方法,但我的代码感觉很笨拙

在下面的例子中,首先我用=定义方法,然后我被迫对要使用的部分使用call方法。但这似乎是一个笨拙的解决办法,所以我想知道是否有一个更干净的解决方案

class Human
  constructor: (@name, @height, @weight) ->

  _realWeight = ->
    @weight

  answerWeight: ->
    console.log(_realWeight.call(@) - 5)

$ ->
  ken = new Human('Ken', 165, 70)
  ken.answerWeight()
TL;博士 没有

更长的答案 在javascript/coffeescript中只有一种方法可以获得真正的私有数据:闭包

首先,让我们考虑一些替代方案:

符号

因为符号是唯一的,所以它们可用于创建psuedo专用数据: 只有在对其键控的符号有引用时,才能访问该属性:

foo = Symbol('I am unique')
bar = {}
bar[foo] = "I am almost private"
无法访问foo的代码无法轻松访问bar的属性,除了Object.getOwnPropertySymbols。所以不容易打破,但易碎

下划线

典型的命名约定是,前缀或后跟下划线的属性/方法是“私有”的,外部调用程序不能使用它们。然而,运行时并没有以任何方式强制执行“隐私”

让我们来谈谈闭包

简单闭包示例

makeFoo = (something) -> getSomething: -> something
foo = makeFoo(3)
foo.something      # undefined
foo.getSomething() # 3
Foo = null
do ->
  privateData = new WeakMap()
  getSomething = -> privateData.get(this)
  Foo = class Foo
    constructor: (something) -> privateData.set(this, something)
    getSomething: getSomething


foo = new Foo(3)
foo.something              # undefined
foo.getSomething()         # 3
new Foo(42).getSomething() # 42
foo instanceof Foo         # true
现在,除了调用该方法之外,无法获取传递给构造函数的参数。这种模式虽然在咖啡脚本中稍微优雅一些,但仍然有点蹩脚。大量重复的函数对象。对于只获取一些东西来说并不坏,但是添加一堆方法,它会很快变得丑陋。而且,JIT编译器通常不像
foo=new foo()
那样容易优化。幸运的是,ES 2015为救援做出了贡献:

高级闭包示例

makeFoo = (something) -> getSomething: -> something
foo = makeFoo(3)
foo.something      # undefined
foo.getSomething() # 3
Foo = null
do ->
  privateData = new WeakMap()
  getSomething = -> privateData.get(this)
  Foo = class Foo
    constructor: (something) -> privateData.set(this, something)
    getSomething: getSomething


foo = new Foo(3)
foo.something              # undefined
foo.getSomething()         # 3
new Foo(42).getSomething() # 42
foo instanceof Foo         # true
现在,
Foo
的所有实例都共享一个
getSomething
副本,而不是每个实例都有自己的副本。weakmap隐藏在IIFE创建的闭包中,并且由于
weakmap
的“弱”部分,当实例被垃圾收集时,私有数据也将被收集。现在,您还可以享受编译器优化
新创建的
对象的好处。最后但并非最不重要的一点是,
instanceof
仍能正常工作(直到它正常工作为止)


weakmap
并非在所有浏览器中都受支持(例如,它的11或半身像)。有垫片,但不能完全填充。垫片是否足够接近是您必须做出的决定。

JavaScript中没有私有属性,因此CoffeeScript中也没有私有属性。您真正拥有的是在
Human
函数范围内定义的函数。使用
Function.prototype.call
Function.prototype.apply
是您所能做的一切。