JavaScript切片没有参数或括号(代码在CodeMirror sql-hint.js)



我正在将优秀的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"; }
}

如果你想检查foobar是否存在于obj中,你需要这样做:

console.log(obj.foo); // returns "function obj.foo()"
console.log(obj.bar); // returns "undefined"

你不能在javascript中定义接口,所以你没有其他选择来检查一个对象中是否存在一个属性/方法。

正如@Jamie所说,任何非假的东西都被评估为真,所以在上面的例子中

  • obj.foofunction obj.foo(),当在if语句(或任何布尔上下文)中使用时,它是true
  • obj.barundefined,在if语句中使用时将是false

另一种方法是:

if(typeof list.slice === "function") return list[item];

这个更长,但更明显。

不确定,但我认为你可以这样做:

if(typeof list === "array" || typeof list === "object")
    return list[item];

我认为这是最不言自明的。

最新更新