Javascript 通过设计检查是否真的很糟糕?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4734986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:50:08  来源:igfitidea点击:

Is checking for true explicity bad by design?

javascriptweakly-typed

提问by Raynos

Is it considered bad to explicitly check for the boolean true. Would it be better to do a simple if(success)?

显式检查布尔值是否被认为是错误的。做一个简单的会更好if(success)吗?

I've seen various jokes made about how if (someBoolean === true)is horrible code in a strongly typed language but is it also considered bad in weakly typed languages?

我看过各种关于if (someBoolean === true)强类型语言中糟糕的代码的笑话,但在弱类型语言中它也被认为是糟糕的吗?

This would apply for any weakly typed language that does type coercion on an if statement.

这适用于对 if 语句进行类型强制的任何弱类型语言。

A specific example would be :

一个具体的例子是:

var onSuccess = function (JSONfromServer) {
    // explicitly check for the boolean value `true`
    if (JSONfromServer === true) {
         // do some things
    }
}

// pass it to an ajax as a callback
doSomeAjax(onSuccess);

[Edit]

[编辑]

In this particular case the success variable is any valid JSON returned from a server. So it could be anything. if its the boolean true then a success happened. If it's some error handling object then it will be handled. If it's something else then it will probably be handled quietly.

在这种特殊情况下,成功变量是从服务器返回的任何有效 JSON。所以它可以是任何东西。如果它的布尔值为真,那么就成功了。如果它是某个错误处理对象,那么它将被处理。如果是别的东西,那么它可能会被悄悄地处理。

The question was is getting the server to return trueas JSON and checking for a good way to handle the case where the action succeeded.

问题是让服务器以trueJSON 形式返回并检查处理操作成功情况的好方法。

I wanted to avoid being specific to JavaScript & AJAX though.

不过,我想避免特定于 JavaScript 和 AJAX。

采纳答案by Andrzej Doyle

I'm in two minds about this myself.

我自己对此有两种看法。

In one respect, the code sample you've posted is good, because of the way Javascript handles type coercion. A simple if (success)would enter the if block so long as successwas truthy- e.g. a non-empty string would do the case. The triple-equals guarantees that successis indeed the boolean value true, which is a stronger guarantee than you'd get with the shorter version (and probably one that you want).

一方面,您发布的代码示例很好,因为 Javascript 处理类型强制的方式。if (success)只要success真的,一个简单的就会进入 if 块——例如,一个非空的字符串就可以做到这一点。三重等号保证success确实是布尔值true,这比使用较短版本(可能是您想要的版本)获得的保证更强。

However, if you needthis - i.e. you don't know whether successwill be a boolean, or a string, or an integer - I'd say that's a code smell in itself. Regardless of how you perform the comparison, I'd always compare with a variable that's going to unavoidably be a boolean; at which point, it doesn't matter which form of comparison is used as they'd be equivalent. In fact, I'd even introduce a "redundant" variable like so:

但是,如果您需要这个 - 即您不知道是success布尔值、字符串还是整数 - 我会说这本身就是一种代码气味。不管你如何进行比较,我总是与一个不可避免地成为布尔值的变量进行比较;在这一点上,使用哪种比较形式并不重要,因为它们是等效的。事实上,我什至会引入一个“冗余”变量,如下所示:

var successCount = items.size(); // or some other way to get an integer
var success = successCount > 0;
if (success) {
   ...
}

So, erm, yeah. I don't think anyone could really complain about the (explicit) use of ===in the comparison because of its functional difference. But by the same token, if you're clearly using boolean successflags then I don't think someone should complain about the short style either.

所以,嗯,是的。我认为没有人会===因为它的功能差异而真正抱怨比较中的(显式)使用。但出于同样的原因,如果您显然使用的是布尔success标志,那么我认为也不应该有人抱怨短样式。

(Regarding your first sentence though, I don't think it's bad to explicitly check for the boolean value true in a dynamically typed language, if that value is actually what you want. It's only superfluous when static typing already constrains the variable to be a boolean.)

(不过,关于你的第一句话,我不认为在动态类型语言中明确检查布尔值 true 是不好的,如果该值实际上是你想要的。当静态类型已经将变量限制为一个时,这只是多余的布尔值。)

回答by Matthew Abbott

With Javascript its worth knowing that beyond boolean true and false, values can be truthyand falsy.

使用 Javascript 值得知道,除了布尔值 true 和 false 之外,值还可以是truefalsy

Consider:

考虑:

if (false)     // evaluates to false.
if (0)         // evaluates to false, 0 is falsy.
if ("")        // evaluates to false, empty strings are falsy.
if (null)      // evaluates to false, null values are falsy.
if (undefined) // evaluates to false, undefined values are falsy.
if (NaN)       // evaluates to false, NaN is falsy.

All other values for objects are truthy.

对象的所有其他值都是真值。

If truthy and falsy values are leading to errors in your logic, you should consider explicitly using ===and !==operators to ensure objects are compared by type and value.

如果真值和假值导致逻辑错误,则应考虑显式使用===!==运算符以确保按类型和值比较对象。

回答by LEMUEL ADANE

Generally, you expect boolean variable names like:

通常,您期望布尔变量名称如下:

success, enabled, pass

to have a true value. So

要有真正的价值。所以

if(success) //or

if(enabled) //or

if(pass) //or

if(enabled) //or

is understandably and logically readable. But if you have variables like:

是可以理解和逻辑可读的。但是如果你有这样的变量:

result, status, port1.bit7

it is better to write:

最好这样写:

if(result == true) //or

if(status == false) //or

if(port1.bit7 == true)

because it is easily understood in that way than the example below:

因为它比下面的例子更容易理解:

if(result)
{
  ....
}

Readability is maintainability.

可读性就是可维护性。

回答by Ivo Wetzel

What can go wrong? Exactly, nothing. In the best case your function does nothing. That's still better then having some random argument be accepted as true.

会出什么问题?没错,什么都没有。在最好的情况下,您的函数什么都不做。这仍然比将一些随机参数接受为true.

If you use trueall the other time, then you should also check explicitly for it.

如果您一直使用true其他时间,那么您还应该明确检查它。

While I'm certain in favor of if foo:in Python, there is a big difference here and that is the fact that in the end some random jQuery programmer may come a long and thinks "Oh! It also works with a string and new Boolean()" and uses that.

虽然我肯定赞成if foo:在 Python 中使用,但这里有一个很大的不同,那就是最后一些随机的 jQuery 程序员可能会在很长一段时间内认为“哦!它也适用于字符串和new Boolean()”并使用它.

Concerning Sean's suggestion to use !!it really depends whether you only want a boolean to be accepted or anything that's true. For a clean API I would only accept booleans though.

关于 Sean 使用!!它的建议实际上取决于您是否只希望接受布尔值或任何真实的东西。对于干净的 API,我只接受布尔值。

回答by Andrew Burgess

I've read quite a bit about JavaScript, and I've never seen anyone say that if(success)was a bad practice. I would do it. Are you sure the successparameter will always be boolean? Right now, if that would ever change to something else, you'd have to edit the function. But if you just use if(success), it would work for other "truthy" and "falsey" values, like a string vs. an empty string, or 1 vs 0.

我已经阅读了很多关于 JavaScript 的书,而且我从未见过有人说这if(success)是一种不好的做法。我会做。你确定success参数总是布尔值吗?现在,如果这会变成其他东西,您必须编辑该函数。但是,如果您只使用if(success),它将适用于其他“真实”和“虚假”值,例如字符串与空字符串,或 1 与 0。

If you want to convert whatever that parameter is to its boolean value, you can just double-negate it: !!success; but that's not necessary inside an conditional like that.

如果你要转换不管它的参数是其布尔值,你可以双击否定它:!!success; 但这在这样的条件中是不必要的。

回答by user3094826

To add to this conversation, sessionStorage and localStorage variables can only be stored as strings today, so if you use:

要添加到此对话中, sessionStorage 和 localStorage 变量今天只能存储为字符串,因此如果您使用:

sessionStorage.setItem('completed',true);

It will actually be converted to a string and stored as 'true'. I've seen many people writing methods and conversions to manipulate this value so that they can use an if statement using a boolean value, where a simple

它实际上将转换为字符串并存储为“true”。我见过很多人编写方法和转换来操作这个值,以便他们可以使用使用布尔值的 if 语句,其中一个简单的

if sessionStorage.getItem('completed') === 'true';

would suffice and is perfectly legible and maintainable in my opinion.

在我看来就足够了,并且完全清晰易读。

回答by Derek Litz

Is it code smell or language smell or an implementation detail or a matter of convention?

是代码异味还是语言异味,还是实现细节或约定问题?

Really, it depends on the situation.

真的,这取决于情况。

Putting all false values and all true values into a bucket simplifies things, until the differences matters, be it bad code design or because it really does matter for some reason.

将所有错误值和所有真实值放入一个桶中可以简化事情,直到差异很重要,无论是糟糕的代码设计还是因为某些原因确实很重要。

In the same vein Hoare apologized for inventing the nullreference, which is as close to the root of this truthy problem as I see. JavaScript's design just confounds the issue by adding even more truthy values, leading many to just advocate explicit checking to avoid hard to track down errors (Douglas Crockford). The JavaScript community has accepted the language itself, is a bit stuck. The Python core team advocates the the opposite as the language design seems to be set on simplifying things, not confounding them, and the core team is still planning for change in the language. Small, iterative changes is the essence of large improvements over time, be it convention, or language design.

同样,霍尔为发明null参考文献而道歉,它与我所看到的这个真实问题的根源非常接近。JavaScript 的设计只是通过添加更多真实值来混淆问题,导致许多人只提倡显式检查以避免难以追踪的错误(Douglas Crockford)。JavaScript 社区已经接受了语言本身,有点卡住了。Python 核心团队主张相反,因为语言设计似乎旨在简化事物,而不是混淆事物,并且核心团队仍在计划语言的变化。随着时间的推移,小的、迭代的变化是大改进的本质,无论是约定还是语言设计。

Both are good strategies for their particular situation. I am not saying that this is the exclusive source of improvement, but that is a major source of improvement at this time.

两者都是针对其特定情况的好策略。我并不是说这是改进的唯一来源,但这是目前改进的主要来源。

For example Trueand Falseare actually subclasses of an intin Python, 0 and 1 specifically. This has several design benefits. Then PEP8 advocates to prefer doing

例如TrueFalse实际上是intPython中 an 的子类,特别是0 和 1。这有几个设计好处。然后 PEP8 提倡更喜欢做

if a_reference:
    pass

The only time Nonereally even needs to be used in Python is when specifying an optional parameter.

None在 Python 中真正需要使用的唯一时间是指定可选参数时。

def foo(bar=optional): # NOTE I made up this idealistic construct
    """Looks good at the surface"""
    pass

def foo(bar=None):
    """But this is clear to the programmer"""
    pass

JavaScript implicitly has all variables as optional:

JavaScript 隐式地​​将所有变量都设为可选:

function foo(x, y, z) {
    // Certainly not clear to the programmer.
}

And Crockford advocates explicitly checking things to try and add some clarity to the language.

克罗克福德提倡明确检查事物以尝试为语言增加一些清晰度。

if (foo === undefined) {
    // pass
}

Basically JavaScript added the Null Reference # 2, known as undefined. I also think it is funny that the JavaScript language is so poorly considered by the programming community they think it is a fair trade off to add the complexity of using something like CoffeeScript, GWT, Pyjamas, just to have a better client side language. Of course, I do not agree in the added complexity, but it is sadly true that some people may benefit, at least temporarily, and get the job at hand done faster, instead of dealing with JavaScript.

基本上 JavaScript 添加了 Null Reference #2,称为undefined. 我还认为有趣的是,编程社区对 JavaScript 语言的考虑如此之差,他们认为增加使用 CoffeeScript、GWT、Pyjamas 之类的复杂性是一种公平的权衡,只是为了拥有更好的客户端语言。当然,我不同意增加的复杂性,但遗憾的是,有些人可能会受益,至少是暂时的,并且更快地完成手头的工作,而不是处理 JavaScript。

I do think this is a foolish decision in the long run, though.

不过,从长远来看,我确实认为这是一个愚蠢的决定。