简体   繁体   English

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

[英]Why does JSHint dislike ternaries for method calls on objects?

JSHint give the following error: JSHint给出以下错误:

Expected an assignment or function call and instead saw an expression. 期望一个赋值或函数调用,而是看到一个表达式。

For the following line of code: 对于以下代码行:

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

It highlights the final ) on someMethod so I assume the error is there. 它突出了someMethod上的最后一个)所以我假设错误就在那里。 The code works and JSHint doesn't have a problem when I change it to if () {} else {} syntax. 代码工作,当我将其更改为if () {} else {}语法时,JSHint没有问题。 I don't mind the longer syntax but I'd like to learn why JSHint says this and if this is a bad practice. 我不介意更长的语法,但我想了解为什么JSHint会说这个,如果这是一个不好的做法。

The biggest piece of confusion may come from the terminology. 最大的困惑可能来自术语。 Is someObject.someMethod() not a function call? someObject.someMethod()不是函数调用吗?

JSHint says about expressions, or expr : JSHint说关于表达式,或expr

This option suppresses warnings about the use of expressions where normally you would expect to see assignments or function calls. 此选项禁止显示有关表达式使用的警告,通常您希望看到分配或函数调用。 Most of the time, such code is a typo. 大多数时候,这样的代码是一个错字。 However, it is not forbidden by the spec and that's why this warning is optional. 但是,规范并不禁止这样做,这就是为什么这个警告是可选的。

While JSLint says: 虽然JSLint说:

An expression statement is expected to be an assignment or a function/method call or delete. 表达式语句应该是赋值或函数/方法调用或删除。 All other expression statements are considered to be errors. 所有其他表达式语句都被视为错误。

AFAIK, there's no problem in doing what you're doing only that it will issue a warning because it would expect you to use an if..else statement, but you can turn this off in JSHint with: AFAIK,做你正在做的事情没有问题,因为它会发出警告,因为它会期望你使用if..else语句,但你可以在JSHint中关闭它:

/*jshint expr:true */

Well, in general it's considered bad practice to call a function using the ternary operator(s), without assigning the return value (which is what you seem to be doing). 好吧,一般来说,使用三元运算符调用函数被认为是不好的做法,而没有分配返回值(这就是你似乎在做的事情)。
Also, it could be worth checking what JSHint has to say about the following code: 此外,值得检查JSHint对以下代码的说法:

(aFunctionOrNull || someObject.someMethod)();

If aFunctionOrNull is undefined (or null, or falsy), the logical-or-bit will cause the expression to evaluate to someObject.someMethod , and the resulting value of that is invoked (a reference to a function object, hopefully). 如果aFunctionOrNull未定义(或null或falsy),则逻辑或位将导致表达式计算为someObject.someMethod ,并调用其结果值(对函数对象的引用,希望如此)。 This gives you the opportunity to write your code more "fail-safe" without the bulk of a nested ternary: 这使您有机会在没有大量嵌套三元的情况下编写更加“自动防故障”的代码:

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

The grouped expression is now bound to evaluate to a truthy value, so no errors are thrown there. 分组表达式现在被绑定为评估为真值,因此不会抛出任何错误。
To avoid JSHint nagging about your not doing anything with the return value, either assign it to a variable (which I don't really like doing), or add a little operator to the mix: 为了避免JSHint唠叨你没有对返回值做任何事情,要么将它分配给变量(我不喜欢这样做),要么添加一个小运算符:

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

On your last question: someObject.someMethod is indeed a function call. 关于你的最后一个问题: someObject.someMethod确实是一个函数调用。 More specifically, it's a call to a function object in the someObject 's context. 更具体地说,它是在someObject的上下文中调用函数对象
For those who don't know this: JS functions are objects, and the called context is either explicitly set using the bind method (defined on the Function.prototype ) or ad-hoc : 对于那些不知道这一点的人:JS函数是对象,并且使用bind方法(在Function.prototype上定义)或ad-hoc显式设置被调用的上下文:

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

An easy way to think of it is that JS functions just float around aimlessly in memory/space/time, until they are called via a reference, the context of that reference is then passed to the function object, to determine what object it'll interact with. 想到它的一个简单方法是JS函数只是在内存/空间/时间中漫无目的地浮动,直到通过引用调用它们,然后将该引用的上下文传递给函数对象,以确定它将是什么对象与。。。相互作用。 This is, sadly, the global object by default, or null in strict mode. 遗憾的是,这是默认情况下的全局对象,或者在严格模式下为null

There error is because a ternary is an expression. 有错误是因为三元是一种表达。 You could use it to set a variable: 您可以使用它来设置变量:

var result = a ? b : c;

Notice that the ternary evaluates to either b or c . 请注意,三元评估为bc It's an expression. 这是一种表达方式。

That said, the warning (I believe) comes from the notion that ternaries suffer poorer readability than an if...else block. 也就是说,警告(我相信)来自于三元组的可读性比if...else块更差的概念。 The code above can be rewritten 上面的代码可以重写

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

Which is easier to read than a ternary. 这比三元书更容易阅读。 JSHint does as much to promote readable code as it does valid code. JSHint尽可能地促进可读代码,因为它有效的代码。 If you're comfortable including these expressions in your code, go ahead and disable the warnings for expressions. 如果您愿意在代码中包含这些表达式,请继续并禁用表达式警告。 (It's what I would do.) (这就是我要做的。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM