【问题标题】:Utility functions to instantiate instance of a CoffeeScript class that extends a pre-existing object用于实例化扩展现有对象的 CoffeeScript 类实例的实用程序函数
【发布时间】:2016-07-14 09:50:00
【问题描述】:

所以我一直在使用 CoffeeScript 中的原型继承,特别是如何编写继承自特定对象而不是另一个类的 CoffeeScript 类,类似于 Crockford 的对象函数。本质上,我想做的是编写一个可以从传入其构造函数的特定对象继承的类。不幸的是,我相信如果不求助于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

现在,我非常喜欢第二种方法,因为它返回的是一个新类,然后您可以使用常规构造函数语法。只有一个问题:虽然使用extendObject 创建的对象正确标识为Examples,但使用extendObjectMaker 返回的构造函数创建的对象标识为Fs,并且不是Example 的实例。

console.log test1 instanceof Example # True
console.log test2 instanceof Example # False

鉴于这些函数使用几乎完全相同的代码,我很难弄清楚它们为何表现出不同的行为。那么,有谁知道为什么test2 没有显示为Example,以及我需要进行哪些更改才能这样做?

【问题讨论】:

  • 看来您的网站不适合这个 :)
  • 呃,为什么会这样?
  • 天哪,我很抱歉!移动端的 Stackoverflow 有另一个 stackexchange 网站的配色方案!

标签: inheritance coffeescript prototype javascript-objects


【解决方案1】:

查看 CoffeeScript 源代码:http://coffeescript.org/v1/annotated-source/nodes.html#section-60

CoffeeScript 对构造函数调用的处理方式有所不同,具体取决于它们是使用 splat (args...) 调用还是不使用。

如果您或者使用new maker [2]...调用extendObjectMaker 按如下方式重写您的函数,您的代码将给出所需的结果:

extendObjectMaker = (parent, Class) ->
  F = (anon...) -> Class.apply(@, anon)
  F:: = Object.create parent
  F::constructor = Class
  (args...) -> new F args...

【讨论】:

  • 很遗憾,链接现在失效了
  • 更新了!请注意,这仅与 CoffeeScript 1.x 相关 - 不确定 CoffeeScript 2 如何处理不同的构造函数调用。
猜你喜欢
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
  • 2014-08-02
  • 2014-05-04
  • 2012-07-16
  • 1970-01-01
相关资源
最近更新 更多