【问题标题】:CoffeeScript: How to return a array From class?CoffeeScript:如何从类返回数组?
【发布时间】:2011-11-17 07:38:11
【问题描述】:

CoffeeScript 中的这个类有什么问题??

@module "Euclidean2D", ->
  class @Point
    constructor: (x,y) -> 
      return if Float32Array? then Float32Array([ x, y ]) else Array(x,y)

我希望它表现得像:

p = new Point(1.0,2.0);
p[0] == 1.0
p[1] == 2.0

但是用 Jasmine 测试我得到“预期未定义等于 1”。

describe "Point", ->

    beforeEach ->
      @point = new Euclidean2D.Point(1.0,2.0)

    it "extracts values", ->
      (expect @point[0]).toEqual 1.0
      (expect @point[1]).toEqual 2.0

CoffeeScript 或 Jasmine 是否有错误??

所有这些都在一个模块中,例如:

@module = (names, fn) ->
  names = names.split '.' if typeof names is 'string'
  space = @[names.shift()] ||= {}
  space.module ||= @module
  if names.length
    space.module names, fn
  else
    fn.call space

在 Chrome 控制台中我得到:

a = new Euclidean2D.Point(1.0,2.0)
-> Point
a[0]
undefined
b = new Float32Array([1.0,2.0])
-> Float32Array
b[0]
1

编辑:,再次......对不起

结合使用@brandizzi 和@arnaud576875 答案已解决。官方 CoffeeScript Wiki 中提出的 @module 不起作用。结果是:

class @Point
        constructor: (x, y) ->
            return if Float32Array? then Float32Array([ x, y ]) else Array(x,y)

【问题讨论】:

    标签: javascript arrays indexing coffeescript


    【解决方案1】:

    您应该使用new 来实例化对象:

    p = new Euclidean2D.Point(1.0,2.0)
    

    如果你想从构造函数中返回一个数组,请显式执行:

    constructor: (x,y) -> 
      return if Float32Array? then Float32Array([x,y]) else Array(x,y)
    

    (默认情况下,Coffeescript 不会从构造函数返回值,所以你必须明确地这样做。)


    你也可以这样做:

    class @Point
      constructor: (x,y) ->
        @[0] = x
        @[1] = y    
    

    【讨论】:

    • 新的在那里,对不起.. 但我想创建一个 Float32Array 而不仅仅是 Array.. 如果不支持 Float32Array 那么我使用 Array
    • 然后在构造函数中的if Float32Array? ... 之前添加一个返回值(默认情况下,coffeescript 没有来自构造函数的return 值)
    • 好的,改成那样了..它仍然给出未定义..改变了问题以反映现在的情况。
    • 它在这里工作:jsfiddle.net/neEp4/96;尝试清除缓存/重新编译脚本
    • 你为什么使用“class Euclidean2D”?在实际中,是一样的吗?
    【解决方案2】:

    您正在定义一个构造函数,但期望它的行为类似于函数。但是,构造函数只是在要返回的对象中设置值。由于您的构造函数没有在初始化对象中设置任何属性,因此它确实没有用。

    你有一些选择:

    1. 将类初始化为@amaud sugested。

    2. 按照@amaud 的建议从构造函数返回值(这对我来说没有多大意义。我觉得这不是构造函数的功能。在这种情况下,解决方案#3 似乎更好)。

    3. 定义一个函数而不是一个类。恕我直言,是最简单、最实用的解决方案

      @Point = (x, y) ->
          if Float32Array? then Float32Array([x,y]) else Array(x,y)
      
    4. 如果您希望 Point 成为 Float32ArrayArray 的特化,请使用选项 #1,但让 Point 从您想要的类继承:

      superclass = if Float32Array? then Float32Array else Array  
      
      class @Point extends superclass
        constructor: (x,y) ->
          @[0] = x
          @[1] = y
      

    编辑:@amaud676875 发表了一个有趣的问题作为评论。由于合理的答案会涉及一些代码,因此我将答案发布为编辑。

    @amaud,为了验证您的观点,我编写了以下 CoffeeScript 模块:

    class Float32Array extends Array
      first: -> # Just for testing
        @[0]
    
    
    superclass = if Float32Array? then Float32Array else Array
    
    class @Point extends superclass
      constructor: (x,y) ->
        @[0] = x
        @[1] = y
    

    然后我在控制台中导入了模块:

    coffee> point = require './point'
    { Point: { [Function: Point] __super__: [ constructor: [Object], first: [Function] ] },
     Float32Array: { [Function: Float32Array] __super__: [] } }
    

    并创建了Point:

     coffee> p = new point.Point 3, 2
     [ 3, 2 ]
    

    这个Point 具有来自Float32Arrayfirst() 方法:

     coffee> p.first()
     3
    

    instanceof 说它也是Float32Array 的一个实例:

    coffee> p instanceof point.Float32Array
    true
    

    所以我打赌new Point x, y 返回一个Float32Array 的实例。当然它也是Point的一个实例,因为Pointis-aFloat32Array,使用经典的OOP表达式是没有问题的。

    【讨论】:

    • 你确定new Point(x,y) 真的返回一个 Float32Array 实例吗?好像没有
    • @amaud 我在帖子中作为编辑回复。看看它是否能澄清/理解情况。
    • 谢谢!它也适用于本机 Float32Array 吗? (参见class Float32Array extends Array)。对我来说,这些类型化数组似乎有点特别,我不确定你是否会继承这些优点。
    • 用那个解决了.. 非常感谢,还需要删除@module,使用 amaud 类 Euclidian2D 来 git 一些命名空间
    • @arnaud 老实说,我以前从未见过这门课。我很想用原生的来测试它。我怎样才能访问它?
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    相关资源
    最近更新 更多