首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Javascript:函数参数和arguments[]

Javascript:函数参数和arguments[]
EN

Stack Overflow用户
提问于 2013-05-22 20:50:07
回答 3查看 1.7K关注 0票数 3

我是一个Javascript新手,所以请原谅我的基本问题。

我正在研究‘面向Web开发人员的专业Javascript’,在第3章“理解参数”一节中,讨论了使用arguments[]关键字访问函数参数。

其中一个示例显示您可以修改arguments[]中的值:

代码语言:javascript
复制
function twoNums(num1, num2) {
    arguments[1] = 10;
    console.log(arguments[0] + num2);
}

twoNums(4,8);  output = 14

但它接着说:“这种效果只有一种方式:更改命名的参数不会导致参数中相应值的更改。”

但是,将代码更改为:

代码语言:javascript
复制
function twoNums(num1, num2) {
    num2 = 10;
    console.log(arguments[0] + arguments[1]);
}

twoNums(4,8);  output = 14

结果是相同的输出,所以'arguments1‘中的值肯定在变化。

这是:

  • 书中的错误?
  • 我理解上的错误?
  • 写完书后Javascript有什么变化吗?

谢谢,

尼尔

答:答案的组合解决了我的问题。谢谢大家。

EN

回答 3

Stack Overflow用户

发布于 2013-05-22 20:58:32

从外观来看,书中有一个错误:如果您重新分配传递的任何参数,arguments对象将发生更改(都引用相同的值)。

也许,这本书的意思是:

代码语言:javascript
复制
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是个坏主意,因为改变任何对象的行为并不是最好的想法(consolewindow.)删除并随机添加方法。

如果您想了解更多关于arguments或其他MDN是来帮忙的的细节。我没有看过所有的代码示例,但是AFAIKT没有有效地更改arguments对象的代码。

一段时间前,我想我读过一篇关于这个问题的文章--道格拉斯·克罗克福德( Douglas ),他举了一个例子,说明改变arguments对象实际上如何导致意想不到的行为(参数交换位置等等)。

编辑:

我原以为我不会进入严格模式,但正如bfavaretto的回答所指出的:严格模式实际上确实使arguments对象成为只读对象。这真是个好消息,现在我更有理由喜欢JS的做法了。ES6将引入块作用域,并可能使arguments对象一直都是只读的(至少,我希望如此)。

票数 2
EN

Stack Overflow用户

发布于 2013-05-22 20:59:11

它应该是这样工作的,除非是在严格的模式下:

代码语言:javascript
复制
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 20

ES5规范解决了第10.6节上的问题。

注1对于非严格模式函数,数组索引(在15.4中定义)命名参数对象的数据属性,其数值名称值小于对应函数对象的形式参数数,这些参数最初在函数的执行上下文中与相应的参数绑定共享值。这意味着更改属性将更改参数绑定的相应值,反之亦然。如果删除该属性,然后重新定义该属性,或者将该属性更改为访问器属性,则此对应关系将中断。对于严格的模式函数,参数对象属性的值只是传递给函数的参数的副本,在属性值和形式参数值之间没有动态联系。

也许它在ES3上的工作方式不同(以前的版本),但我对此表示怀疑(因为他们必须为严格模式添加一个特例)。

有趣的事实:函数中存在eval调用会影响参数对象在某些浏览器中的行为,这是非常奇怪的。非标准functionName.arguments引用的使用也有影响.参见为什么未执行的eval会对某些浏览器中的行为产生影响?,以及我对此的回答。

票数 2
EN

Stack Overflow用户

发布于 2013-05-22 21:04:25

它只有在严格的模式下才能这样工作。

代码语言:javascript
复制
 "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

我建议你使用它:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16701353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档