可能重复:
is object empty?
update: (id, data) ->
toUpdate = @find(id)
if toUpdate isnt {}
console.log "hi mom"
console.log toUpdate
toUpdate.setProperty(key, value) for own key, value of data
return toUpdate
find:(id) ->
result = record for record in @storage when record.id is id
return result or {}
鉴于以下Mocha测试
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'
......很奇怪,不是吗?
答案 0 :(得分:14)
CoffeeScript的is
(AKA ==
)只是JavaScript的===
和isnt
(AKA !=
)只是JavaScript& #39; s !==
。所以你的条件:
if toUpdate isnt {}
将始终为真,因为toUpdate
且对象文字{}
永远不会是同一个对象。
但是,如果@find
可以返回已知的&#34;空&#34;在常量中可用的对象,然后您可以使用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
演示:http://jsfiddle.net/ambiguous/7JGdq/
因此,您需要另一种方法来检查toUpdate
是否为空。您可以在toUpdate
中计算属性:
if (k for own k of toUpdate).length isnt 0
或者您可以使用上面列出的特殊EMTPY
常量方法。还有其他各种方法来检查空对象,Ricardo Tomasi提出了一些建议:
_.isEmpty
,这基本上是for
循环方法,有一些特殊的案例处理和短路。_.values
,因此您可以查看_(toUpdate).values().length
。这会在内部调用map
,如果可用,它将是本机map
函数。JSON.stringify(toUpdate) is '{}'
来浏览JSON,这对我来说似乎有点脆弱而且相当圆润。Object.keys
代替for
循环:Object.keys(toUpdate).length isnt 0
。 keys
并不支持任何地方,但它可以与Node,最新的非IE浏览器和IE9 +一起使用。Object.isEmpty
,jQuery有$.isEmptyObject
。短路for
循环似乎是检查空虚的最快方法:
(obj) ->
for k of toUpdate
return true
false
假设您不需要own
来避免迭代错误的事情。但鉴于这只是一个测试套件而且空洞测试几乎肯定不会成为您代码中的瓶颈,我会选择您拥有的Underscore,Sugar或jQuery中的任何一个(如果您需要)可移植性并且必须处理通常的浏览器废话),Object.keys(x).length
如果您知道它可用,(k for own k of toUpdate).length
如果您没有图书馆并且必须处理浏览器废话并且不是确定toUpdate
将是一个简单的对象。