Coffeescript 咖啡脚本不是';t空对象

Coffeescript 咖啡脚本不是';t空对象,coffeescript,Coffeescript,可能重复: 考虑到以下摩卡测试 describe '#update', -> it 'should return an updated record from a given id and data when the record exists', -> boogie = createData() archive = new Archive("Dog") dog = archive.create(boogie) result

可能重复:

考虑到以下摩卡测试

describe '#update', ->
    it 'should return an updated record from a given id and data when the record exists', ->
      boogie = createData()
      archive = new Archive("Dog")
      dog = archive.create(boogie)
      result = archive.update(1, {name:"Chompie", age:1})
      result.name.should.eql "Chompie"
      result.age.should.eql 1
      result.emotion.should.eql dog.emotion

    it 'should return an updated record from a given id and data when the record does not exist', ->
      boogie = createData()
      archive = new Archive("Dog")
      dog = archive.create(boogie)
      result = archive.update(50, {name:"Chompie", age:1})
      result.should.not.exist
结果是

Archive #update should return an updated record from a given id and data when the record exists: hi mom
{ id: 1,
  validationStrategies: {},
  name: 'Boogie',
  age: 2,
  emotion: 'happy' }
  ✓ Archive #update should return an updated record from a given id and data when the record exists: 1ms
    Archive #update should return empty when the record does not exist: hi mom
{}
    ✖ 1 of 13 tests failed:
    1) Archive #update should return empty when the record does not exist:
    TypeError: Object #<Object> has no method 'setProperty'
Archive#当记录存在时,更新应返回来自给定id和数据的更新记录:hi mom
{id:1,
验证策略:{},
名字:'布吉',
年龄:2岁,
情感:“快乐”}
✓ 存档#当记录存在时,更新应返回给定id和数据的更新记录:1ms
存档#当记录不存在时,更新应返回空:hi mom
{}
✖ 13项测试中有1项失败:
1) 存档#当记录不存在时,更新应返回空:
TypeError:对象#没有方法“setProperty”

…令人惊讶,不是吗?

咖啡脚本的
(又名
=
)只是JavaScript的
=
不是
(又名
!=
)只是JavaScript的
==。所以你的情况是:

if toUpdate isnt {}
将始终为true,因为
toUpdate
和对象文本
{}
将永远不是同一个对象

但是,如果
@find
可以返回常量中可用的已知“空”对象,则可以使用
isnt

EMPTY = {}

find: ->
    # ...
    EMPTY
后来:

if toUpdate isnt EMPTY
    #...
例如,考虑这个简单的代码:

a = { }
b = { }
console.log("a is b: #{a is b}")
console.log("a isnt b: #{a isnt b}")
这将在控制台中为您提供以下信息:

a is b: false
a isnt b: true
但这是:

class C
    EMPTY = { }
    find: -> EMPTY
    check: -> console.log("@find() == EMPTY: #{@find() == EMPTY}")

(new C).check()
他会说:

@find() == EMPTY: true
演示:

因此,您需要另一种方法来检查
toUpdate
是否为空。您可以在
toUpdate
中计算属性:

if (k for own k of toUpdate).length isnt 0
或者,您可以使用上面概述的特殊
EMTPY
常量方法。检查空对象还有多种其他方法,​ 提出了一些建议:

  • 下划线提供了一种基本上是
  • for
    循环的方法,带有一些特殊的案例处理和短路
  • 下划线还提供了一些选项,以便您可以查看
    (更新).values().length
    。这将在内部调用,如果可用,这将是本机
    map
    函数
  • 您甚至可以使用
    JSON来查看JSON。stringify(toUpdate)是“{}”
    ,这对我来说似乎有点脆弱,而且相当全面
  • 您可以使用而不是
    for
    循环:
    Object.keys(toUpdate)。长度不是0
    <代码>键
  • 并非处处都受支持,但它可以与Node、最新的非IE浏览器和IE9+配合使用
  • Sugar也有,jQuery也有
  • 对于
    回路,短路
    似乎是检查空位的最快方法:

    (obj) ->
        for k of toUpdate
            return true
        false
    

    这假设您不需要
    own
    来避免重复错误的内容。但考虑到这只是一个测试套件,而且空测试几乎肯定不会成为代码中的瓶颈,我会选择下划线、Sugar或jQuery中的任何一种(如果您需要可移植性并且必须处理常见的浏览器废话),
    Object.keys(x).length,如果您知道它将可用,以及
    (k表示自己的toUpdate的k)。length
    如果你没有库,不得不处理浏览器的废话,并且不能确定toUpdate
    将是一个简单的对象。

    CoffeeScript的
    (AKA
    =
    )只是JavaScript的
    =
    不是
    (AKA
    )只是JavaScript的
    !=
    。因此您的条件:

    if toUpdate isnt {}
    
    将始终为true,因为
    toUpdate
    和对象文本
    {}
    将永远不是同一个对象

    但是,如果
    @find
    可以返回常量中可用的已知“空”对象,则可以使用
    isnt

    EMPTY = {}
    
    find: ->
        # ...
        EMPTY
    
    后来:

    if toUpdate isnt EMPTY
        #...
    
    例如,考虑这个简单的代码:

    a = { }
    b = { }
    console.log("a is b: #{a is b}")
    console.log("a isnt b: #{a isnt b}")
    
    这将在控制台中为您提供以下信息:

    a is b: false
    a isnt b: true
    
    但这是:

    class C
        EMPTY = { }
        find: -> EMPTY
        check: -> console.log("@find() == EMPTY: #{@find() == EMPTY}")
    
    (new C).check()
    
    他会说:

    @find() == EMPTY: true
    
    演示:

    因此,您需要另一种方法来检查
    toUpdate
    是否为空。您可以在
    toUpdate
    中计算属性:

    if (k for own k of toUpdate).length isnt 0
    
    或者您可以使用上面介绍的特殊的
    EMTPY
    常量方法。检查空对象有多种其他方法,​ 提出了一些建议:

  • 下划线提供了一种基本上是
  • for
    循环的方法,带有一些特殊的案例处理和短路
  • 下划线还提供了可以查看
    (toUpdate).values().length
    。这将在内部调用,如果可用,这将是本机的
    map
    函数
  • 您甚至可以使用
    JSON来查看JSON。stringify(toUpdate)是“{}”
    ,这对我来说似乎有点脆弱,而且相当全面
  • 您可以使用
    来代替
    for
    循环:
    对象。键(toUpdate)。长度不是0
    键不是到处都支持的,但它可以用于节点、最新的非IE浏览器和IE9+
  • Sugar也有,jQuery也有
  • 对于
    回路,短路
    似乎是检查空位的最快方法:

    (obj) ->
        for k of toUpdate
            return true
        false
    

    这假设您不需要
    own
    来避免重复错误的内容。但考虑到这只是一个测试套件,空测试几乎肯定不会成为代码中的瓶颈,我会选择下划线、Sugar或jQuery中的任何一个(如果您需要可移植性,并且必须处理常见的浏览器废话),
    Object.keys(x).length
    如果您知道它将可用,以及
    (k代表自己的k toUpdate).length
    如果你没有库,必须处理浏览器的废话,并且不确定
    toUpdate
    是否是一个简单的对象。

    因此它会明确检查相同的引用,而不仅仅是相同的类型和值?什么是检查空对象的惯用方法…啊,玩得好。这感觉几乎是邪恶的,但实际上是错误的delicious
    toUpdate.setProperty(key,value)表示自己的key,数据的value当((k表示toUpdate的own k)。长度不是0)
    isEmpty()
    添加到
    对象。prototype
    ?我知道纯粹主义者对弄乱原型会很挑剔,但是