用于实例化扩展现有对象的 CoffeeScript class 实例的实用函数
Utility functions to instantiate instance of a CoffeeScript class that extends a pre-existing object
所以我一直在研究 CoffeeScript 中的原型继承,特别是研究如何编写从特定对象而不是另一个 class 继承的 CoffeeScript classes类似于 Crockford 的对象函数。本质上,我想做的是编写一个 class ,它可以从传递给其构造函数的特定对象继承。不幸的是,我认为如果不求助于 setPrototypeOf
,这可能是不可能的,考虑到关于它的相当惊人的警告,我宁愿不这样做。相反,我可能会选择一个可以做类似事情的函数。以下是两种可能性:
a = {foo: 1}
class Example
constructor: (@bar) ->
extendObject = (parent, Class, args...) ->
F = (anon...) -> Class.apply(@, anon)
F:: = Object.create parent
F::constructor = Class
new F args...
extendObjectMaker = (parent, Class) ->
F = (anon...) -> Class.apply(@, anon)
F:: = Object.create parent
F::constructor = Class
F
maker = extendObjectMaker a, Example
test1 = extendObject a, Example, 2
test2 = new maker 2
现在,我非常喜欢第二种方法,因为基本上它返回的是一个新的 class,然后您可以使用常规构造函数语法。只有一个问题:虽然使用 extendObject
创建的对象正确识别为 Example
s,但使用 extendObjectMaker
返回的构造函数创建的对象识别为 F
s,并且不是 F
s 的实例Example
.
console.log test1 instanceof Example # True
console.log test2 instanceof Example # False
鉴于这些函数使用几乎完全相同的代码,我很难弄清楚为什么它们表现出不同的行为。那么,有谁知道为什么 test2
没有显示为 Example
,我需要更改什么才能让它显示出来?
查看 CoffeeScript 源代码:http://coffeescript.org/v1/annotated-source/nodes.html#section-60。
CoffeeScript 以不同方式处理构造函数调用,具体取决于它们是使用 splat (args...
) 调用还是不使用 splat 调用。
如果您 使用 new maker [2]...
或 调用 extendObjectMaker 重新编写您的函数,您的代码将给出所需的结果如下:
extendObjectMaker = (parent, Class) ->
F = (anon...) -> Class.apply(@, anon)
F:: = Object.create parent
F::constructor = Class
(args...) -> new F args...
所以我一直在研究 CoffeeScript 中的原型继承,特别是研究如何编写从特定对象而不是另一个 class 继承的 CoffeeScript classes类似于 Crockford 的对象函数。本质上,我想做的是编写一个 class ,它可以从传递给其构造函数的特定对象继承。不幸的是,我认为如果不求助于 setPrototypeOf
,这可能是不可能的,考虑到关于它的相当惊人的警告,我宁愿不这样做。相反,我可能会选择一个可以做类似事情的函数。以下是两种可能性:
a = {foo: 1}
class Example
constructor: (@bar) ->
extendObject = (parent, Class, args...) ->
F = (anon...) -> Class.apply(@, anon)
F:: = Object.create parent
F::constructor = Class
new F args...
extendObjectMaker = (parent, Class) ->
F = (anon...) -> Class.apply(@, anon)
F:: = Object.create parent
F::constructor = Class
F
maker = extendObjectMaker a, Example
test1 = extendObject a, Example, 2
test2 = new maker 2
现在,我非常喜欢第二种方法,因为基本上它返回的是一个新的 class,然后您可以使用常规构造函数语法。只有一个问题:虽然使用 extendObject
创建的对象正确识别为 Example
s,但使用 extendObjectMaker
返回的构造函数创建的对象识别为 F
s,并且不是 F
s 的实例Example
.
console.log test1 instanceof Example # True
console.log test2 instanceof Example # False
鉴于这些函数使用几乎完全相同的代码,我很难弄清楚为什么它们表现出不同的行为。那么,有谁知道为什么 test2
没有显示为 Example
,我需要更改什么才能让它显示出来?
查看 CoffeeScript 源代码:http://coffeescript.org/v1/annotated-source/nodes.html#section-60。
CoffeeScript 以不同方式处理构造函数调用,具体取决于它们是使用 splat (args...
) 调用还是不使用 splat 调用。
如果您 使用 new maker [2]...
或 调用 extendObjectMaker 重新编写您的函数,您的代码将给出所需的结果如下:
extendObjectMaker = (parent, Class) ->
F = (anon...) -> Class.apply(@, anon)
F:: = Object.create parent
F::constructor = Class
(args...) -> new F args...