Javascript明显的疯狂 [英] Javascript apparent madness

查看:77
本文介绍了Javascript明显的疯狂的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能重复:

空的JavaScript数组的冲突布尔值

[ ([] == false), ([] ? 1 : 2) ]

返回 [true,1]

换句话说,空列表在布尔上下文中逻辑上为真,但等于 false

In other words an empty list is logically true in a boolean context, but is equal to false.

我知道使用 === 解决了这个问题,但这背后的解释是什么显然完全不合逻辑选择?

I know that using === solves the issue, but what is the explanation behind this apparently totally illogical choice?

换句话说,这被认为是语言中的一个错误,这是一种无意识的事情,刚刚发生并且无法修复,因为它已经太晚或者真的在设计中语言有人认为这种表现很酷很酷疯狂,我确信这对许多程序员来说很混乱?

In other words is this considered a mistake in the language, something unintentional that just happened and that cannot be fixed because it's too late or really in the design of the language someone thought it was cool to have this kind of apparent madness that I'm sure is quite confusing for many programmers?

对于这种情况如何发生的技术解释同时令人惊讶和惊吓,但我对此更感兴趣这个设计的背后是什么。

The technical explanation of how this happens is at the same time amazing and scaring, I was however more interested in what is behind this design.

我接受了非常详细的Nick Retallack解释,即使它只是关于为什么 [] == false 的技术原因是真的:令人惊讶的是它发生的原因是 [] 转换为字符串是一个空字符串,空字符串数值是特殊的,而不是显然更符合逻辑的 NaN 。例如,对象({})== false 返回false,因为空对象的字符串表示形式不是空字符串。

I accepted very detailed Nick Retallack explanation, even if it's only about the technical reasons of why []==false is true: surprisingly enough it happens is because [] converted to string is an empty string and the empty string numeric value is special cased to be 0 instead of the apparently more logical NaN. With an empty object for example the comparison ({}) == false returns false because the string representation of an empty object is not the empty string.

我的好奇心仍然是所有这一切都是未曾预料到的(现在不幸在标准中固化)。

My curiosity still remains about all this being just unanticipated (and now unfortunately solidified in a standard).

推荐答案

让我们获得技术支持。我将使用 ECMAScript标准中的引用来解释逻辑262

Let's get technical. I'll explain the logic with quotes from the ECMAScript Standard 262.

表达式 []? 1:2 非常简单:


11.12条件运算符(?:)


  • 让lref成为评估LogicalORExpression的结果。

  • 如果 ToBoolean(GetValue( lref))是真的,然后是


    • 让trueRef成为评估第一个AssignmentExpression的结果。

    • 返回GetValue(trueRef)。

    • Let lref be the result of evaluating LogicalORExpression.
    • If ToBoolean(GetValue(lref)) is true, then
      • Let trueRef be the result of evaluating the first AssignmentExpression.
      • Return GetValue(trueRef).

      • 让falseRef是评估第二个AssignmentExpression的结果。

      • 返回GetValue(falseRef)

      9.2 ToBoolean


      • 未定义:false

      • Null:false

      • 布尔值:结果等于输入参数(无转换)。

      • 数字:结果为假如果参数是+ 0,0或NaN;否则结果为真。

      • 字符串:如果
        参数为空String(其长度为零),则结果为false;否则
        结果为真。

      • 对象:true

      • Undefined: false
      • Null: false
      • Boolean: The result equals the input argument (no conversion).
      • Number: The result is false if the argument is +0, 0, or NaN; otherwise the result is true.
      • String: The result is false if the argument is the empty String (its length is zero); otherwise the result is true.
      • Object: true

      所以这是真的。

      现在对于所发生的事情的疯狂骑行当你使用double equals运算符时。也许这有助于解释为什么你永远不应该这样做。

      Now for the wild ride of what happens when you use the double equals operator. Perhaps this will help explain why you should never do this.

      第11.9.3节:抽象等式比较算法中解释了==的行为。

      The behavior of == is explained in in section 11.9.3: The Abstract Equality Comparison Algorithm.

      对于x == y,其中x = []且y = false,会发生这种情况:

      For x == y where x = [] and y = false, this happens:


      11.9.3:抽象等式比较算法

      如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)

      If Type(y) is Boolean, return the result of the comparison x == ToNumber(y)

      9.3 ToNumber

      结果为 + 0 如果参数是
      false

      现在我们有[] == 0

      Now we have [] == 0


      11.9.3:抽象等式比较算法

      如果Type(x)是Object而Type(y)是String或Number,则返回
      比较结果 ToPrimitive(x)== y

      If Type(x) is Object and Type(y) is either String or Number, return the result of the comparison ToPrimitive(x) == y.

      9.1 ToPrimitive

      返回Object的默认值。通过调用
      对象的 [[DefaultValue]] 内部方法,传递可选提示PreferredType来检索对象
      的默认值。对于8.12.8中所有本机ECMAScript对象,[b [规范值)]内部方法
      的行为由此规范
      定义。

      Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.

      8.12.8 DefaultValue:

      当调用O的[[DefaultValue]]内部方法而没有
      提示时,它表现得很好好像提示是数字

      When the [[DefaultValue]] internal method of O is called with no hint, then it behaves as if the hint were Number


      • 设valueOf是调用[[Get]]内部方法的结果对象O的参数为valueOf。

      • 如果IsCallable(valueOf)为真,则


        • 设val为调用valueOf的[[Call]]内部方法的结果,其中O为此值和空参数列表。

        • 如果val是原始值,则返回val


        • 让str是调用 toString 的[[Call]]内部方法的结果,其中O作为此值和空参数列表。

        • 如果str是原始值返回str

        • Let str be the result of calling the [[Call]] internal method of toString, with O as the this value and an empty argument list.
        • If str is a primitive value, return str.

        我假设这首先尝试valueOf然后拒绝它,因为结果是你开始使用的相同数组。然后它调用Array上的toString,它似乎普遍实现为以逗号分隔的值列表。对于像这样的空数组,会产生空字符串。

        I assume this first attempts valueOf and then rejects it because the result is the same array you started with. It then calls toString on Array, which seems to be universally implemented as a comma separated list of its values. For empty arrays like this one, that results in empty string.

        现在我们有''== 0

        Now we have '' == 0


        11.9.3:抽象等式比较算法

        如果Type(x)是String和Type(y )是数字,返回
        比较结果 ToNumber(x)== y

        If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y

        9.3.1 ToNumber应用于字符串类型

        为空或仅包含空格的StringNumericLiteral是
        转换为 + 0

        A StringNumericLiteral that is empty or contains only white space is converted to +0.

        现在我们有0 == 0

        Now we have 0 == 0


        11.9.3:抽象等式比较算法

        如果x与y的数值相同,返回true

        If x is the same Number value as y, return true

        太棒了。这是真的。虽然这里有相当复杂的方式。

        Awesome. It's true. Pretty convoluted way of getting here though.

        这篇关于Javascript明显的疯狂的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆