学生问了一个问题
1 2 3 4 5 6 7 8 9 | function funcA(arr) { arr[0] = arr[2] } function funcB(a, b, c=3) { c = 10 funcA(arguments) return a + b + c } console.log(funcB(1,1,1)) // 12 |
而如果funcB的c没有默认值
1 2 3 4 5 6 7 8 9 | function funcA(arr) { arr[0] = arr[2] } function funcB(a, b, c) { c = 10 funcA(arguments) return a + b + c } console.log(funcB(1,1,1)) // 21 |
以上两段代码的结果不同,这种现象是为什么?
这涉及到两个知识点:
1)这是因为严格模式和非严格模式的时候arguments对象的行为有所不同:
非严格模式:arguments对象和形参是互相引用的
1 2 3 4 5 6 7 8 9 10 11 | function func(a) { arguments[0] = 99; // 更新了arguments[0] 同样更新了a console.log(a); } func(10); // 99 function func(a) { a = 99; // 更新了a 同样更新了arguments[0] console.log(arguments[0]); } func(10); // 99 |
严格模式:arguments对象和形参互相无关
1 2 3 4 5 6 7 8 9 10 11 12 13 | function func(a) { "use strict" arguments[0] = 99; // 不会更新a console.log(a); } func(10); // 10 function func(a) { "use strict" a = 99; // 不会更新arguments[0] console.log(arguments[0]); } func(10); // 10 |
非严格模式下的这个行为是很讨厌的,这也是为什么我们不喜欢潜规则,如果你不小心,它就会把东西弄得很复杂。
2)当函数中使用了参数的解构、默认值或…rest参数,则函数内部自动按严格模式解释
尝试运行下面这个例子,观察结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | < script > function func(a) { arguments[0] = 99 // 更新了arguments[0] 同样更新了a console.log(a) } func(10) // 10 </ script > < script > function func(a) { arguments[0] = 99 // 更新了arguments[0] 同样更新了a console.log(a) } func(10) // 99 </ script > < script > function func(a=1) { arguments[0] = 99 console.log(a) } func(10) // 10 </ script > < script > function func(a, ...b) { arguments[0] = 99 console.log(a) } func(10) // 10 </ script > |