为什么JavaScript参数对象会因赋值给参数而发生变化?
Why are JavaScript Arguments objects mutated by assignment to parameter?
这种行为背后的基本原理是什么?
function f(x) {
console.log(arguments[0]);
x = 42;
console.log(arguments[0]);
}
f(1);
// => 1
// => 42
也许这是一个真正的错误。ECMAScript规范的哪个部分定义了这种行为?
实际上,在严格模式下,这不会发生,正如你在这里看到的。
如果你阅读ECMA标准10.6节,特别是注释1,你会看到:
对于非严格模式函数,数组索引(在15.4中定义)命名参数对象的数据属性谁的数字名称值最初小于相应函数对象的形式参数的数量与函数执行上下文中相应的参数绑定共享它们的值。这意味着改变属性改变参数绑定的相应值,反之亦然。这种通信中断了这样的属性将被删除,然后重新定义,或者将该属性更改为访问器属性。对于严格模式函数中,参数对象的属性值只是传递给函数和的参数的副本属性值和形式参数值之间没有动态联系。
简而言之,这就是说,在非严格模式下,命名函数参数作为arguments
对象中项的别名进行操作。因此,更改命名参数的值将更改等效arguments
项的值,反之亦然。这不是一个错误。这是预期的行为。
作为一篇社论,依赖这种行为可能不是一个好主意,因为它可能导致一些非常混乱的代码。同样,这样的代码,如果在严格模式下执行,将不再工作。
x
的变化反映在arguments[0]
中,因为arguments
的索引可能是匹配命名参数的getter/setter 。这在步骤11.c中定义。Ii of 10.6:
在上面的步骤中注意到,这要求strict为false,在这种情况下,调用
添加name作为列表元素mappedNames。
让g是调用MakeArgGetter抽象操作的结果,参数为name和env。
让p是调用MakeArgSetter抽象操作的结果,参数为name和env。
调用map传递ToString(indx)的[[DefineOwnProperty]]内部方法,属性描述符{[[Set]]: p, [[Get]]: g, [[Configurable]]: true}和false作为参数。
f
时为x
提供一个值:
f() // undefined, undefined (no argument, no getter/setter)
f(1) // 1, 42
- 函数参数中的数据与指定变量之间的任何性能差异
- 使用Express捕获参数
- 参数变量出现ngTable指令问题
- AngularJS:我可以跳过函数参数回调吗
- 如何使用skip参数使用angular ui引导进行服务器端分页
- 要求未定义JS回调参数
- 我的jQuery插件参数没有正确启动,遇到了问题
- 获取@ResponseBody的一部分作为主干和Spring MVC控制器之间的参数
- 单击页面上的链接后高度发生变化
- jquery设置为使用参数运行
- 在变换的绝对位置发生变化时制作动画's参数
- AngularJS-在一个数组中使用多个不断变化的参数进行过滤
- 变量用作函数参数后发生变化
- 如何将变化参数传递给setTimeout
- 为什么JavaScript参数对象会因赋值给参数而发生变化?
- 对init和参数的API调用发生了变化
- Js,jquery,easyui,参数在传递给函数时发生了变化
- 为什么' this '在作为字符串或引用传递函数参数时发生变化
- 如何在mithril.js中检测模型参数变化事件
- 递归函数(插件?)与不断变化的参数,直到达到数(jQuery)