为什么JSHint不喜欢对象的方法调用的三元组?

时间:2012-12-26 20:31:20

标签: javascript jshint

JSHint给出以下错误:

  

期望一个赋值或函数调用,而是看到一个表达式。

对于以下代码行:

(aFunctionOrNull) ? aFunctionOrNull() : someObject.someMethod();

它突出显示)上的最终someMethod,因此我假设错误存在。代码有效,当我将其更改为if () {} else {}语法时,JSHint没有问题。我不介意更长的语法,但我想了解为什么JSHint会说这个,如果这是一个不好的做法。

最大的困惑可能来自术语。 someObject.someMethod()不是函数调用吗?

3 个答案:

答案 0 :(得分:5)

JSHint谈到表达式,或expr

  

此选项禁止有关使用表达式的警告   通常你会看到分配或函数调用。最   当时,这样的代码是一个错字。但是,它并没有被禁止   规范,这就是为什么这个警告是可选的。

虽然JSLint说:

  

表达式语句应该是赋值或者   函数/方法调用或删除。所有其他表达式语句都是   被认为是错误。

AFAIK,做你正在做的事情是没有问题的,它会发出警告,因为它会期望你使用if..else语句,但是你可以在JSHint中关闭它:

/*jshint expr:true */

答案 1 :(得分:4)

嗯,一般来说,使用三元运算符调用函数被认为是不好的做法,而没有指定返回值(这就是你似乎正在做的事情)。
另外,它可能值得检查JSHint对以下代码有什么看法:

(aFunctionOrNull || someObject.someMethod)();

如果aFunctionOrNull未定义(或为null或falsy), logical-or-bit 将导致表达式计算为someObject.someMethod,结果值为被调用的(希望对函数对象的引用)。这使您有机会在没有大量嵌套三元的情况下编写更多“fail-safe”的代码:

(aFunctionOrNull || someObject.someMethod || function(){})();

分组表达式现在必须评估为真值,因此不会抛出任何错误 为了避免JSHint唠叨你没有对返回值做任何事情,要么将它分配给一个变量(我真的不喜欢这样做),要么添加一个小算子:

~(aFunctionOrNull || someObject.someMethod || function(){})();//bitwise not
!(aFunctionOrNull || someObject.someMethod || function(){})();//logical not, doesn't really matter which one

关于你的上一个问题:someObject.someMethod确实是一个函数调用。更具体地说,它是在someObject的上下文中调用函数对象
对于那些不知道这一点的人:JS函数是对象,并且使用bind方法(在Function.prototype上定义)或 ad-hoc :

var referenceToMethod = someObject.someMethod;
referenceToMethod();//<-- inside the function objects, this now points to the global object

一种简单的方法来思考它是JS函数只是在内存/空间/时间内漫无目的地浮动,直到通过引用调用它们,然后将该引用的上下文传递给函数对象,以确定哪个对象它会与之互动。遗憾的是,这是默认情况下的全局对象,或者是严格模式下的null

答案 2 :(得分:3)

错误是因为三元是一种表达。您可以使用它来设置变量:

var result = a ? b : c;

请注意,三元评估为bc。这是一种表达方式。

那就是说,警告(我相信)来自于三元组的可读性比if...else块更差的概念。上面的代码可以重写

var result;
if (a) {
    result = b;
} else {
    result = c;
}

这比三元书更容易阅读。 JSHint与有效代码一样,可以提升可读代码。如果您愿意在代码中包含这些表达式,请继续并禁用表达式警告。 (这就是我要做的。)