我正在将优秀的CodeMirror中的sql-hint.js代码改编到我的邪恶设计中…
但是我遇到了一行超出我的JavaScript。我不明白,也找不到任何解释。
它是codemmirror -masteraddonhintsql-hint.js中的第34行,它看起来像这样:
function getItem(list, item) {
if (!list.slice) return list[item]; // <--- THIS LINE!!!!!
for (var i = list.length - 1; i >= 0; i--) if (getText(list[i]) == item)
return list[i];
}
我不明白的命令是:
if (!list.slice)
没有参数,也没有括号。这到底是怎么回事?
请注意不是这样写:
if (!list.slice())
JavaScript是一种真/假语言,这意味着我们可以根据某些标准断言给定对象是真还是假。在JavaScript中,总是报告为false的值有:false
, 0 (zero)
, "" (empty string)
, null
, undefined
, NaN
。
这里的检查是为了找出list.slice
是否为undefined
,如果是,则返回索引为item
的列表项。
如果你要console.log(list.slice)
,你会期望function () {}
。但是我们不想调用这个函数,因为如果slice
未定义,那么它将失败。
如果你有
var obj = {
foo: function () { return "string"; }
}
如果你想检查foo
和bar
是否存在于obj中,你需要这样做:
console.log(obj.foo); // returns "function obj.foo()"
console.log(obj.bar); // returns "undefined"
你不能在javascript中定义接口,所以你没有其他选择来检查一个对象中是否存在一个属性/方法。
正如@Jamie所说,任何非假的东西都被评估为真,所以在上面的例子中
-
obj.foo
是function obj.foo()
,当在if
语句(或任何布尔上下文)中使用时,它是true
-
obj.bar
是undefined
,在if
语句中使用时将是false
另一种方法是:
if(typeof list.slice === "function") return list[item];
这个更长,但更明显。
不确定,但我认为你可以这样做:
if(typeof list === "array" || typeof list === "object")
return list[item];
我认为这是最不言自明的。