arguments对象和参数的互相引用
学生问了一个问题
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没有默认值
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对象和形参是互相引用的
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对象和形参互相无关
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参数,则函数内部自动按严格模式解释
尝试运行下面这个例子,观察结果
<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>