我正在学习JavaScript,对arguments属性数组非常困惑。
我有一个函数,它接受一个参数并返回它。当我传递该参数并使用arguments[0] = value重新分配它时,它正在更新该值。
function a(b) {
arguments[0] = 2;
return b;
}
console.log(a(1)); //returns 2
但是,当我没有参数调用相同的函数时,它会返回undefined。
function a(b) {
arguments[0] = 2;
return b;
}
console.log(a()); //returns undefined
但是即使我通过了undefined,这个值也会更新。
function a(b) {
arguments[0] = 2;
return b;
}
console.log(a(undefined)); //returns 2
我认为,如果不将参数传递给JavaScript函数,它会自动创建该参数并将其赋值给undefined,更新后它应该会反映更新后的值,对吗?
a()和a(undefined)也是一样的,对吧?
发布于 2019-01-23 08:59:28
分配给arguments索引只会更改相关的参数值(让我们称它为n-th参数),如果函数至少使用n参数调用。arguments对象的数值索引属性本质上是设置器(和getter):
http://es5.github.io/#x10.6
下面的斜体字是我对这个过程与这个问题的关系的评论:
(设)
args(be)传递给[Call]内部方法的实际参数
len是args中的元素数。indx = len - 1。indx >= 0**,** (因此,当没有参数传递给函数时,下面的循环将不会运行)。)(为正在创建的参数对象赋值,这里称为map__:)
name作为列表mappedNames的一个元素。g是使用参数name和env调用MakeArgGetter抽象操作的结果。p是使用参数name和env调用MakeArgSetter抽象操作的结果。map传递ToString(indx)的[Get]内部方法,属性描述符{[Set]:p,[Get]:g,[Configurable]:true}和false作为参数。因此,如果函数是在没有参数的情况下调用的,那么arguments[0]上就不会有一个setter,因此重新分配它将不会更改索引0处的参数。
同样的情况也发生在其他指示符中--如果调用一个带有1个参数的函数,但该函数接受两个参数,则分配给arguments[1]不会更改第二个参数,因为arguments[1]没有一个setter:
function fn(a, b) {
arguments[1] = 'bar';
console.log(b);
}
fn('foo');
所以
a()和a(undefined)是一回事,对吗?
情况并非如此,因为第二个结果是索引0上带有setter和getter的arguments对象,而第一个则不是。
请注意,arguments和函数参数之间的这种奇怪的交互作用只存在于草率模式中。在严格模式下,对arguments的更改不会对单个参数标识符包含的值产生任何影响:
'use strict';
function a(b) {
arguments[0] = 2;
return b;
}
console.log(a(1)); //returns 1
发布于 2019-01-23 08:45:59
ECMA 262 9.0 2018在9.4.4参数--外来对象中描述这种行为
附注1: 参数外来对象的整数索引数据属性,其数值名称值小于对应功能对象的形式参数数,其值最初与函数的执行上下文中的相应参数绑定共享它们的值。这意味着更改属性将更改参数绑定的相应值,反之亦然。如果删除该属性,然后重新定义该属性,或者将该属性更改为存取性质,则会中断此对应关系。如果参数对象是普通对象,则其属性值只是传递给函数的参数的副本,而且属性值与形式参数值之间没有动态链接。
总之,
'sloppy mode'中,那么所有参数都映射到它们的命名变量,如果长度对应于给定的参数,或者'strict mode'中,那么在传递参数之后绑定就会丢失。这仅在较早版本的ECMA 262 7.0 2016中可读。它在9.4.4参数--外来对象中描述这种行为
附注1: 对于非严格函数,参数对象的整数索引数据属性,其数值名称值小于对应函数对象的形式参数数,最初在函数的执行上下文中与相应的参数绑定共享它们的值。这意味着更改属性将更改参数绑定的相应值,反之亦然。如果删除该属性,然后重新定义该属性,或者将该属性更改为访问器属性,则此对应关系将中断。对于严格的模式函数,参数对象属性的值只是传递给函数的参数的副本,在属性值和形式参数值之间没有动态联系。
发布于 2019-01-23 08:50:14
这是因为参数不像Array,它是一个具有整数索引数据键和属性长度的对象,如果长度等于零,就意味着没有参数
function a(b) {
arguments[0] = 2;
console.log(arguments.length)
return b;
}
a(1); // length 1 returns 2
console.log(a()); // length 0 returns undefined
https://stackoverflow.com/questions/54323086
复制相似问题