blog
blog copied to clipboard
PHP 和 JSON 都说 `_.isEmpty()` 是个好方法
PHP 和 JSON 都说 _.isEmpty() 是个好方法
背景
我们在通过后端 API 获取 JSON 数据时,有时会遇到这个问题:
在需要输出为对象的地方,如果没有数据,以前端的习惯来说,我们会期待收到一个空对象 {};但实际上,此时我们往往会收到一个空数组 []。
前端在检查和处理此类数据时,会感到稍许不便。如果考虑不周,还会引发错误。
原因
在 PHP 中,与 JavaScript 数组和对象对应的概念都是数组;而且 PHP 实际上并不区分索引数组和关联数组,只是允许开发者通过数组键名的约定来产生这两种数组的效果。也就是说,对于空数组,由于它不包含键名,无法判断它是“索引数组”还是“关联数组”。因此,PHP 的 json_encode() 方法在处理空数组时,一律将其编码为 []。
由此可见,要求后端来改变这种情况恐怕不太容易,还是需要前端在处理类似数据的时候做个容错判断(我们常说“发送时要严格、接收时要宽松”嘛)。那么,怎样判断既简单又方便呢?
解决方案
这里就要隆重推出 _.isEmpty() 啦!请看以下代码:
_.isEmpty() //true
_.isEmpty(null) //true
_.isEmpty(undefined) //true
_.isEmpty('') //true
_.isEmpty({}) //true
_.isEmpty([]) //true
_.isEmpty('foo') //false
_.isEmpty([foo, bar]) //false
_.isEmpty({foo: bar}) //false
同时我们注意到,即使后端将空数据输出为 null,仅用这一个方法也可以一并判断。
注意事项
需要注意的是,不能把这货当成 toBoolean() 来用。这样用是有坑的:
_.isEmpty(1) //true
_.isEmpty(0) //true
_.isEmpty(NaN) //true
_.isEmpty(true) //true
_.isEmpty(false) //true
_.isEmpty(_.isEmpty) //true
所以,只应该用它来判断一个数据集合是否为空。
才发现可以判断数组,他的文档上目前居然还是这么写的
Returns true if object contains no values.
坑啊
@edokeh 是啊,Underscore 的 API 文档并不是很详细。这个方法是个典型的例子,没交待清楚。 开源小项目都这样,要弄清楚还是得看源码。(作者故意的?)
在文档方面 jQuery 算做得好的,能火起来也不是偶然的。相比之下 Zepto 的文档就是个渣。
哈哈,zepto 确实问题挺大的,作者已经 3 个多月没有更新了,而且从 1.0 RC1 到 1.0 Release 居然花了一年时间。。。
才发现可以判断数组,他的文档上目前居然还是这么写的
Returns true if object contains no values.
坑啊
@edokeh 不好意思老毛病又犯了,想继续扯一下这个 API 的文档。其实它这里的 object 实际上是用来标识参数的,因为这个 API 的用法是这样写的 _.isEmpty(object)。而它的示例代码表明了它可以用于数组:
_.isEmpty([1, 2, 3]); //=> false
话说回来,Underscore 文档中的 collection / array / object 三个概念倒真是不太容易区分。_.isEmpty() 的行为实际上跟 collection 下面的部分 API 很相似,归在 object 下确实很容易误导。
呵呵,collection 与 array 初看的时候确实被绕了一下