如何使用CoffeeScript扩展一个类,同时将构造参数传递给super?
例如:
class List extends Array
# Some other stuff to make it work...
list = new List(1,2,3)
console.log list
[1, 2, 3]
如何使用CoffeeScript扩展一个类,同时将构造参数传递给super?
例如:
class List extends Array
# Some other stuff to make it work...
list = new List(1,2,3)
console.log list
[1, 2, 3]
通常情况下,不需要额外的代码就可以工作;除非被明确覆盖,否则会使用父构造函数:
class A
constructor: ->
console.log arg for arg in arguments
class B extends A
new B('foo') # output: 'foo'
问题并不是 Array 没有constructor
方法:
coffee> Array.constructor
[Function: Function]
问题在于Array
是非常奇怪的东西。虽然从原则上讲,数组只是对象,但实际上它们存储方式不同。因此,当您尝试将该构造函数应用于不是数组的对象(即使它通过了instanceof Array
测试),它不起作用。List
传递给期望真正的数组的东西)。出于这个原因,我建议将List
实现为包装器,围绕一个数组实例,而不是尝试使用来自本地对象类型的继承。super
时,那确实传递了所有参数!这种行为是从Ruby借来的。因此class B extends A
constructor: ->
super
会将所有参数传递给 A
的构造函数,同时
class B extends A
constructor: ->
super()
会调用A
的构造函数,并且不带任何参数。
@arr = Array::slice.call arguments, 0
(将arguments方法转换为对象的标准方法),然后你需要将每个数组方法实现为简单的传递(例如: push: -> @arr.push.apply arr, arguments
, toString: -> @arr.toString()
等),最后添加自己的List
方法。 - Trevor Burnham@[method] = (=> method.apply @arr, arguments) for method of @arr
。 - Trevor Burnhamclass List extends Array
constructor: ->
@push arguments...
toString: ->
@join('-')
list = new List(1, 2)
list.push(3)
list.toString()
=>
'1-2-3'
extends
时,期望超类也是 CoffeeScript。如果您使用的是非 CoffeeScript 类,例如原始问题中的 Array
,则可能会遇到问题。_super
,而这可能不是编译后的 JS 的预期用法。class MyClass extends SomeJsLib
constructor: ->
_super.call @, arg1, arg2
如果您只想将调用者的参数传递:
class MyClass extends SomeJsLib
constructor: ->
_super.apply @, arguments
.apply
调用带有动态数量参数的特定函数非常容易。args = [1, 2, 3]
f = measurement.clone
f.apply measurement, args
classfactory = (f) ->
class extension extends f
apply
到超类的构造函数中。classwitharguments = (f, args) ->
class extension extends f
constructor: () ->
extension.__super__.constructor.apply @, args
使用这个新工厂
args = [1, 2, 3]
instance = new (classwitharguments Measurement, args)
有什么想法?评论?建议?我没有考虑到的限制?请告诉我。
Array
的奇怪行为。 - Mitja