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

JavaScript slice without parameters or brackets (code in CodeMirror sql-hint.js)

我正在将优秀 CodeMirror 中的 sql-hint.js 代码改编成我的邪恶设计...

但是我遇到了一行JavaScript,这是我无法理解的。我不明白,也找不到任何解释。

它是 CodeMirror-master\addon\hint\sql-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 是一种 truthy/falsy 语言,这意味着我们可以根据某些标准断言给定对象是真还是假。在 JavaScript 中,始终报告为 false 的值是:false0 (zero)"" (empty string)nullundefinedNaN

此处的检查是为了查明 list.slice 是否为 undefined,如果是,则返回索引为 item.

的列表项

如果您要 console.log(list.slice),您会期待 function () {}。我们不想调用该函数,因为如果 slice 未定义,那将失败。

如果你有

var obj = {
    foo: function () { return "string"; }
}

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

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

您无法在 javascript 中定义接口,因此您别无选择来检查对象中是否存在 property/method。

正如@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];

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