这是合法的JavaScript吗?将参数传递给函数并让它们改变它们

Ari*_*iel 12 javascript variables arguments function

这合法吗?它适用于所有浏览器吗?

function func1(a, b, c) {
  //b == 2 here
  change_em(arguments);
  //b should equal 3 here
}

function change_em(args) {
  args[0] = 6;
  args[1]++;
  args[2] = [];
}

func1('foo', 2);
Run Code Online (Sandbox Code Playgroud)

如果您想知道,我需要调整函数中的参数.一个宏是完美的,除了javascript没有.正确地执行它,即将变量传递给函数,然后将它们返回到对象中,然后在调用者中提取它们几乎与复制/粘贴调整函数一样多.

Mik*_*uel 12

它在EcmaScript 3和EcmaScript 5非严格下有效,但在EcmaScript 5严格模式下无效.它适用于所有现代浏览器和大多数旧浏览器.它不应该在严格模式下工作,例如在带有"use strict"指令的Firefox 5中运行时.

来自EcmaScript 5规范部分10.6.11.c.ii

10.6参数对象

...

如果strict为false并且name不是mappedNames的元素,那么

  1. 添加名称作为列表mappedNames的元素.

  2. 设g是使用参数name和env调用MakeArgGetter抽象操作的结果.

  3. 设p是使用参数name和env调用MakeArgSetter抽象操作的结果.

  4. 调用传递给ToString(indx)的地图的[[DefineOwnProperty]]内部方法,属性描述符{[[Set]]:p,[[Get]]:g,[[Configurable]]:true},并将false作为参数.

基本上,arguments对象获取每个索引的setter,以便分配arguments[i]更改位置上命名参数的值i.规范中有语言,反之亦然.

这应该在任何解释器中以非严格模式工作

(function (x) {
  alert("x=" + x + ", arguments[0]=" + arguments[0]);  // Both should be 0
  arguments[0] = 1;
  alert("x=" + x + ", arguments[0]=" + arguments[0]);  // both should be 1
  x = 2;
  alert("x=" + x + ", arguments[0]=" + arguments[0]);  // both should be 2
 })(0);
Run Code Online (Sandbox Code Playgroud)

但是如果你使用use strict指令在Firefox 5上运行上面的内容,你会得到不同的行为:

(function (x) {
  "use strict";

  alert("x=" + x + ", arguments[0]=" + arguments[0]);  // Both should be 0
  arguments[0] = 1;
  alert("x=" + x + ", arguments[0]=" + arguments[0]);  // x=0, arguments[0]=1
  x = 2;
  alert("x=" + x + ", arguments[0]=" + arguments[0]);  // x=2, arguments[0]=1 
 })(0);
Run Code Online (Sandbox Code Playgroud)