14

在调试别人编写的 javascript 时,我遇到了一些我以前从未见过的代码。这是一个示例:

function doSomething() {
    //doing something here...
}

function doItNow() {
    //other logic...
    doSomething && doSomething();    // <=== What's this?
}

函数 doItNow() 中第二行的目的是检查 doSomething 是否存在然后调用它?像这样:

function doItNow() {
    //other logic...
    if (doSomething) {
        doSomething();
    }
}

JSLint 不喜欢它,我宁愿在我的应用程序中不要有错误的代码。有什么见解吗?

4

3 回答 3

7

这确实是一个“速记”。仅当左侧通过 asif()语句时才执行右侧。

Google Closure Compiler 和其他压缩器利用了这一点;如果您的输入是if(a) a(),它将导致a&&a()


您可以对 执行相同的操作||,例如:

if( !a ){
  alert('Not a');
}

可以写成

a || alert('Not a');
于 2010-11-03T20:54:24.560 回答
6

是的,您的两个示例是“等效的”,&&操作员执行短路评估

如果第一个操作数表达式产生一个值(例如null, undefined, 0, NaN, 一个空字符串,当然还有),则不会false计算第二个操作数表达式,如果该值是值,将进行函数调用。

但是如果doSomething没有被声明,你的两个例子都会失败

如果在代码中引用了未声明的标识符,您将收到ReferenceError异常,例如:

function foo() {
  undeclared && undeclared();
}

try {
  foo(); 
} catch (e) {
  alert(e);  // ReferenceError!
}

如果你想:

  1. 确保标识符存在,并且
  2. 确保它是可调用的

你可以:

if (typeof doSomething == 'function') {
  doSomething();
}

typeof运算符可以安全地用于不存在的标识符,此外,通过检查它doSomething是一个函数,您可以确保您能够调用它。

于 2010-11-03T20:56:35.627 回答
1

在比较中调用函数(或赋值等)通常是一个坏主意。人们通常不认为比较会产生副作用。这种情况很简单,可能是合理的,但如果有人不理解约定,他们可能不得不在 StackOverflow 上询问;)

于 2010-11-03T20:57:45.607 回答