Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript中的命名参数和arguments对象_Javascript - Fatal编程技术网

JavaScript中的命名参数和arguments对象

JavaScript中的命名参数和arguments对象,javascript,Javascript,最近,我开始通过Nicholas C.Zakas的《面向Web开发人员的专业JavaScript》一书学习JavaScript,我遇到了一些我自己无法解决的问题 正如标题所说,这都是关于JavaScript函数中的命名参数和参数对象 例如,我们有一段代码: function doAdd(num1 , num2) { arguments[1] = 10; alert(arguments[0] + num2); } doAdd(10 , 20); 书中说arguments对象

最近,我开始通过Nicholas C.Zakas的《面向Web开发人员的专业JavaScript》一书学习JavaScript,我遇到了一些我自己无法解决的问题

正如标题所说,这都是关于JavaScript函数中的命名参数参数对象

例如,我们有一段代码:

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

doAdd(10 , 20);
书中说arguments对象中的值由相应的命名参数自动反映,因此
num2
20的值进入函数,然后通过
arguments[1]
将其覆盖,最后得到10的值。到目前为止一切正常。然后它说

这种效果只有一种:更改命名参数不会导致更改参数中的相应值

问题就从这里开始

我试图稍微修改一下这段代码以理解作者所说的话,但失败了

例如


这次
num2
再次以20的值进入函数,它通过
参数[1]
变为10,然后再次通过命名参数
num2
变为40。警报弹出50,因为更改命名的参数不会导致更改
参数中的相应值。为什么警报不会弹出20

这是因为本书假设您正在使用

如果您在严格模式下运行代码,您将获得给定书中所写内容的预期行为

function doAdd(num1 , num2) {
     "use strict";
     arguments[1] = 10;
     num2 = 40;
     alert(arguments[0] + arguments[1]);
}
doAdd(10 , 20); // this alerts 20, alerts 50 in nonstrict mode
一个鲜为人知的事实是,严格模式的整个要点是避免这种动态范围(这就是为什么参数是固定的,
with
是不允许的,
eval
的行为不同)。除了清晰性的提高,这还允许大幅提高速度

另见:

对于严格模式函数,arguments对象属性的值只是传递给函数的参数的副本,并且属性值和形式参数值之间没有动态链接

这就是NCZ在上下文中引用本书本身的意思:

Strict模式对arguments对象的使用方式进行了若干更改。一是任务,, 如前一个示例中所示,不再有效。num2的值仍然未定义,即使 参数[1]已分配给10。其次,试图覆盖参数的值是一种错误 语法错误。(代码不会执行。)-第82页,语言基础,专业JavaScript,Nicholas C.Zakas

引用

注1对于非严格模式函数数组索引(定义见15.4)arguments对象的命名数据属性(其数值名称值小于相应函数对象的形式参数数)最初与函数执行上下文中的相应参数绑定共享其值这意味着更改属性会更改参数绑定的相应值,反之亦然。

它没有向20发出警报,因为根据ECMA 5.1规范,在非严格模式函数中,使用数字键对arguments对象进行变异,也会更改与数字键对应的实际形式参数


在本例中,当您更改
参数[1]
时,您也在更改第二个参数。同样,当你改变num2时,你也在改变参数[1]

扎卡斯先生的书是错误的。我正在读这本书,我得到了同样的问题。。。非常感谢。这是一次尝试回答,我很抱歉,我刚刚修复了它。@user3649693请留下您的不确定性作为评论,这样我就可以对它做出回应-为未来的访问者。但是我们不是把参数[1](10)的值写得太多了吗?Book假设我们是stict模式,但没有语法错误,脚本运行平稳。这让我有点困惑。@user3649693重新分配参数意味着
参数=[]
或类似的东西。赋值给参数的属性意味着代码看起来像
参数[1]=10
,虽然这是允许的,但它会更改参数的一个副本,而不是参数本身。现在这就不那么容易混淆了。我们如何修改上面的代码,使其在严格模式下抛出语法错误?
function doAdd(num1 , num2) {
     "use strict";
     arguments[1] = 10;
     num2 = 40;
     alert(arguments[0] + arguments[1]);
}
doAdd(10 , 20); // this alerts 20, alerts 50 in nonstrict mode