加性操作符疑问

1、JavaScript高级程序设计中第48页
“如果有一个操作数是对象、数值或布尔值,则调用它们的toString()方法取得相应的字符串值,然后再应用前面关于字符串的规则”

function test(){
    var a=true;
    alert(10+a)
}
test()

如果按照书上讲的运行出来的结果应该是10true
但实际上运行结果是11
2、

function rewrite(num1,num2){
    arguments[1]=100;
    alert(arguments[0]+num2)
    alert(num2)
    alert(arguments[1])
    
}
rewrite(10)

(1)这里的arguments[1]与num2的值不一致,书上说是因为arguments对象的长度由传入参数个数决定(P66)。我不懂这两者有什么关联?
(2)alert(arguments[0]+num2)为什么输出是NaN,而不是10undefined,书上说的是“对于undefined和null,则分别调用String()函数并取得字符串‘undefined’和‘null’”(P48)
以上的书页都是指JavaScript高级程序设计

阅读 2.5k
4 个回答

泻药

问题一

相加的计算:http://www.ecma-international...

Let lprim be ? ToPrimitive(lval).
Let rprim be ? ToPrimitive(rval).

可以看到这里的 ToPrimitive 没有给 PreferredType,所以默认 hint 为 number,优先考虑 valueOf 。10 为 10,a 为 true 都不是 string 不满足

If Type(lprim) is String or Type(rprim) is String

所以两者转为数字

Let lnum be ? ToNumber(lprim).
Let rnum be ? ToNumber(rprim).

true 为 1,相加和为 11

问题二

(1)

看 NOTE1: http://www.ecma-international...

For non-strict functions the integer indexed data properties of an arguments object whose numeric name values are less than the number of formal parameters of the corresponding function object initially share their values with the corresponding argument bindings in the function's execution context. This means that changing the property changes the corresponding value of the argument binding and vice-versa. This correspondence is broken if such a property is deleted and then redefined or if the property is changed into an accessor property. For strict mode functions, the values of the arguments object's properties are simply a copy of the arguments passed to the function and there is no dynamic linkage between the property values and the formal parameter values.

注意这个 less than 。用你上面的例子来说,现在是 non-strict 模式,rewrite(10) 传入 1 个参数,那么 arguments 的索引到 0 为止都是动态绑定的。所以 num2 并没有跟 arguments[1] 绑定在一起。但如果你传入两个或以上的参数,比如 rewrite(10, 1) 就可以观察到两者动态绑定了。

(2)

同理,arguments[0] 为 10,num2 为 undefined,都不是 string,转为 number,undefined 变成 NaN,再加 10 还是 NaN。

补充楼上
alert(arguments[0]+num2)的结果是因为arguments[0]是数值,然后num2转换为数值后再计算,undefined转换为数值为NAN,而任意数值+NAN结果为NAN

定义 a+b
另外,1中的高程的那句话,是在a为字符串的情况下,如果a为数值,则b应优先调用value。

http://www.w3cplus.com/javasc... 有篇有关加号操作符的文章讲的不错,可以看看。

  1. 如果式子中有字符串,转换成字符串相加

var result = 1 + 1 + '123'
console.log(result) // '11123'
相当于 
String(1) + String(1) + '123'

没有字符串

var result = 1 + true
console.log(result) // 2
相当于 
1 + Number(true) // 2

2.

rewrite(10)
function rewrite(num1,num2){
    arguments[1]=100;
    arguments[2]=200;
    console.log(arguments.length)    // 1
    console.log(num2)                // undefined
    console.log(arguments[0]+num2)   // 10 + Number(undefined) => NaN
    console.log(arguments[1])        // 100
    console.log(arguments[2])        // 200
}
rewrite(10 , 20)
2
100
110
200
100

当 rewrite函数传入了1个值 arguments 的length 为1 只有arguments[0] 没有arguments[1] 你强制给他赋值为100并不会使num2的值变为100
当 rewrite函数传入了2个值 arguments 的length 为2 传入的num2= 20 通过arguments[1]=100 使 num2 的值变为了100
为什么输出是NaN, 看对1问题的回答

  • 布尔型与数值型运算的时候会选转换成数值,false = 0, true = 1
  • arguments 引用了传入的所有参数,是伪数组对象,所以其 length 是实际传入参数的个数,按下标(从0开始)可以取每传入的每个参数值。
  • arguments[1] 已经被重新赋值,但是 num2 还是保存着原来传入的参数值,所以二者不同。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏