我是一个Javascript新手,所以请原谅我的基本问题。
我正在研究‘面向Web开发人员的专业Javascript’,在第3章“理解参数”一节中,讨论了使用arguments[]关键字访问函数参数。
其中一个示例显示您可以修改arguments[]中的值:
function twoNums(num1, num2) {
arguments[1] = 10;
console.log(arguments[0] + num2);
}
twoNums(4,8); output = 14但它接着说:“这种效果只有一种方式:更改命名的参数不会导致参数中相应值的更改。”
但是,将代码更改为:
function twoNums(num1, num2) {
num2 = 10;
console.log(arguments[0] + arguments[1]);
}
twoNums(4,8); output = 14结果是相同的输出,所以'arguments1‘中的值肯定在变化。
这是:
谢谢,
尼尔
答:答案的组合解决了我的问题。谢谢大家。
发布于 2013-05-22 20:58:32
从外观来看,书中有一个错误:如果您重新分配传递的任何参数,arguments对象将发生更改(都引用相同的值)。
也许,这本书的意思是:
function f(n1, n2)
{
arguments[0] = 2;
console.log(arguments[0] + arguments[1]);
}
f(1, 2);//logs 4
f(1234,2);//logs 4但是,老实说,这不应该真的重要。arguments对象应被视为只读对象.在JS中坚持“不要改变你不拥有的对象”这句话是个好主意。试图改变Object.prototype是个坏主意,因为改变任何对象的行为并不是最好的想法(console,window.)删除并随机添加方法。
如果您想了解更多关于arguments或其他MDN是来帮忙的的细节。我没有看过所有的代码示例,但是AFAIKT没有有效地更改arguments对象的代码。
一段时间前,我想我读过一篇关于这个问题的文章--道格拉斯·克罗克福德( Douglas ),他举了一个例子,说明改变arguments对象实际上如何导致意想不到的行为(参数交换位置等等)。
编辑:
我原以为我不会进入严格模式,但正如bfavaretto的回答所指出的:严格模式实际上确实使arguments对象成为只读对象。这真是个好消息,现在我更有理由喜欢JS的做法了。ES6将引入块作用域,并可能使arguments对象一直都是只读的(至少,我希望如此)。
发布于 2013-05-22 20:59:11
它应该是这样工作的,除非是在严格的模式下:
function foo(a) {
"use strict";
console.log(a, arguments[0]);
a = 10;
console.log(a, arguments[0]);
arguments[0] = 20;
console.log(a, arguments[0]);
}
foo(1);
// output:
// 1 1
// 10 1
// 10 20ES5规范解决了第10.6节上的问题。
注1对于非严格模式函数,数组索引(在15.4中定义)命名参数对象的数据属性,其数值名称值小于对应函数对象的形式参数数,这些参数最初在函数的执行上下文中与相应的参数绑定共享值。这意味着更改属性将更改参数绑定的相应值,反之亦然。如果删除该属性,然后重新定义该属性,或者将该属性更改为访问器属性,则此对应关系将中断。对于严格的模式函数,参数对象属性的值只是传递给函数的参数的副本,在属性值和形式参数值之间没有动态联系。
也许它在ES3上的工作方式不同(以前的版本),但我对此表示怀疑(因为他们必须为严格模式添加一个特例)。
有趣的事实:函数中存在eval调用会影响参数对象在某些浏览器中的行为,这是非常奇怪的。非标准functionName.arguments引用的使用也有影响.参见为什么未执行的eval会对某些浏览器中的行为产生影响?,以及我对此的回答。
发布于 2013-05-22 21:04:25
它只有在严格的模式下才能这样工作。
"use strict" 参数对象有一个非常不寻常的特性。在非严格模式下,当函数有命名参数时,参数对象的数组元素是包含函数参数的参数的别名。参数对象和参数名称的编号元素与相同变量的两个不同名称类似。用参数名更改参数的值将更改通过arguments[]数组检索的值。相反,通过arguments[]数组更改参数的值会更改参数名检索的值。这里有一个例子澄清了这一点: 函数f(x) { console.log(x);//显示参数参数的初始值= null;//更改数组元素也会更改x!console.log(x);// Now显示"null“}如果参数对象是一个普通数组,这显然不是您会看到的行为。在这种情况下,参数和x最初可以引用相同的值,但对其中一个的更改不会对另一个值产生影响。 参数对象的这种特殊行为在ECMAScript 5的严格模式下被删除,还有其他严格模式的区别。在非严格函数中,参数只是一个标识符.在严格的模式下,它实际上是一个保留字。严格模式函数不能将参数用作参数名或局部变量名,也不能为参数赋值。
下面是关于这个主题的一篇伟大的(和最近的)文章:https://www.inkling.com/read/javascript-definitive-guide-david-flanagan-6th/chapter-8/function-arguments-and
我建议你使用它:)
https://stackoverflow.com/questions/16701353
复制相似问题