为了账号安全,请及时绑定邮箱和手机立即绑定

对于CodeMash 2012的“Wat”Talk中提到的这些奇怪的JavaScript行为

对于CodeMash 2012的“Wat”Talk中提到的这些奇怪的JavaScript行为

茅侃侃 2019-06-01 16:36:10
对于CodeMash 2012的“Wat”Talk中提到的这些奇怪的JavaScript行为这个为CodeMash 2012而作的谈话基本上指出了Ruby和JavaScript的一些奇怪之处。我已经把结果告诉大家了http://jsfiddle.net/fe479/9/.以下列出了JavaScript特有的行为(我不知道Ruby)。我在JSFiddle中发现,我的一些结果与视频中的结果不一致,我不知道为什么。然而,我很想知道JavaScript在每种情况下都是如何在幕后处理的。Empty Array + Empty Array[] + []result:<Empty String>我很好奇+运算符当与JavaScript中的数组一起使用时。这与视频的结果相匹配。Empty Array + Object[] + {}result:[Object]这与视频的结果相匹配。这里发生了什么事?为什么这个东西。是什么+接线员会吗?Object + Empty Array{} + []result[Object]这和录像不匹配。视频显示结果为0,而我得到了[Object]。Object + Object{} + {}result:[Object][Object]这也不匹配视频,如何输出一个变量导致两个对象?也许我的JSFiddle是错的。Array(16).join("wat" - 1)result:NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN执行WAT+1会导致wat1wat1wat1wat1...我怀疑这只是简单的行为,试图从字符串中减去一个数字会导致NaN。
查看完整描述

3 回答

?
桃花长相依

TA贡献1860条经验 获得超8个赞

以下是对你所看到的结果的解释列表(并且应该看到)。我使用的引用来自ECMA-262标准.

  1. [] + []

    当使用加法运算符时,左操作数和右操作数都首先转换为原语(第11.6.1节)。按§9.1,将对象(在本例中为数组)转换为基元返回其默认值,对于具有有效值的对象,该默认值为toString()方法是调用object.toString() (第8.12.8节)。对于数组,这与调用array.join() (第15.4.4.2节)。加入空数组会产生空字符串,因此加法运算符的步骤7返回两个空字符串的连接,即空字符串。

  2. [] + {}

    类似于[] + [],两个操作数首先转换为原语。对于“对象”(§15.2),这也是调用object.toString(),对于非空的、未定义的对象是"[object Object]" (第15.2.4.2节).

  3. {} + []

    这个{}这里不是被解析为一个对象,而是作为一个空块(§12.1,至少只要您没有强迫该语句成为表达式,但稍后会有更多的介绍)。空块的返回值为空,因此该语句的结果与+[]..一元+操作员(第11.4.6节)回报ToNumber(ToPrimitive(operand))..我们已经知道,ToPrimitive([])是空字符串,根据第9.3.1节ToNumber("")是0。

  4. {} + {}

    类似于上一个案例,第一个{}被解析为具有空返回值的块。再一次,+{}是相同的ToNumber(ToPrimitive({})),和ToPrimitive({})"[object Object]"(见[] + {})。所以为了得到…的结果+{},我们必须申请ToNumber在绳子上"[object Object]"..执行以下步骤时第9.3.1节,我们得到NaN因此:

    如果语法不能将字符串解释为字符串数字文学的结果托内姆非数.

  5. Array(16).join("wat" - 1)

    第15.4.1.1节第15.4.2.2节Array(16)创建长度为16的新数组。要获得要加入的参数的值,第11.6.2节步骤5和步骤6表明,我们必须使用以下方法将两个操作数转换为一个数字ToNumberToNumber(1)就是1(§9.3),鉴于ToNumber("wat")再一次是NaN第9.3.1节..的第7步第11.6.2节第11.6.3节口述

    如果任一操作数是非数,结果是非数.

    所以争论到Array(16).joinNaN..第15.4.4.5节(Array.prototype.join),我们得打电话ToString在争论中,也就是"NaN" (§9.8.1):

    如果m非数,返回字符串。"NaN".

    的第10步第15.4.4.5节,我们得到了15个重复的级联"NaN"空字符串,等于你看到的结果。使用时"wat" + 1而不是"wat" - 1作为参数,加法运算符转换1转换为字符串,而不是转换"wat"对一个数字,所以它有效地调用Array(16).join("wat1").

为什么你会看到不同的结果{} + []Case:当使用它作为函数参数时,您是在强迫语句成为表象陈述,这使得无法解析{}作为空块,因此它被解析为空对象文本。


查看完整回答
反对 回复 2019-06-01
?
慕的地8271018

TA贡献1796条经验 获得超4个赞

我第二个@Ventero的解决方案。如果你愿意的话,你可以更详细地了解+转换其操作数。

第一步(第9.1节):将两个操作数转换为原语(原语值为undefinednull、布尔值、数字、字符串;所有其他值都是对象,包括数组和函数)。如果操作数已经是原语,您就完成了。如果不是,它就是一个对象。obj并执行以下步骤:

  1. 打电话

    obj.valueOf()

    ..如果它返回一个原语,您就完成了。直接事例

    Object

    数组自己返回,所以您还没有完成。
  2. 打电话

    obj.toString()

    ..如果它返回一个原语,您就完成了。

    {}

    []

    两者都返回一个字符串,这样您就完成了。
  3. 否则,抛出一个

    TypeError.

对于日期,步骤1和步骤2被交换。您可以如下所示观察转换行为:

var obj = {
    valueOf: function () {
        console.log("valueOf");
        return {}; // not a primitive
    },
    toString: function () {
        console.log("toString");
        return {}; // not a primitive
    }}

互动(Number()首先转换为原语,然后转换为数字):

> Number(obj)valueOf
toStringTypeError: Cannot convert object to primitive value

第二步(第11.6.1节):如果其中一个操作数是字符串,则另一个操作数也转换为字符串,并通过连接两个字符串产生结果。否则,将两个操作数转换为数字,并通过添加它们生成结果。

对转换过程的更详细解释:“什么是JavaScript中的{}+{}?


查看完整回答
反对 回复 2019-06-01
  • 3 回答
  • 0 关注
  • 468 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信