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