2013-01-02 69 views
2

想检查传递给函数的参数,并替换未指定的或者“我不喜欢”的参数。对于这一点,我已经做了以下(我为什么要使用arguments的原因是,我想有一个泛型函数这样做)(node.js的具有相同的结果,只是改变记录仪安慰):更改函数参数

function argtest (x,y,z) { 
    Logger.log ("at begin x="+x+", y="+y+", z="+z); 
    arguments.length=3; // found this somewhere, doesn't help 
    arguments[0]="a"; 
    arguments[1]="b"; 
    arguments[2]="c"; 
    Logger.log ("arguments now:"); 
    for (var i in arguments) { 
    Logger.log ("arguments["+i+"]="+arguments[i]); 
    } 
    Logger.log ("at end x="+x+", y="+y+", z="+z); 
} 
function callArgTest() { 
    argtest(); 
    argtest (1,2,3); 
} 

因此调用callArgTest的结果是:

Logger.log([at begin x=undefined, y=undefined, z=undefined, []]) 
Logger.log([arguments now:, []]) 
Logger.log([arguments[0]=a, []]) 
Logger.log([arguments[1]=b, []]) 
Logger.log([arguments[2]=c, []]) 
Logger.log([at end x=undefined, y=undefined, z=undefined, []]) 
Logger.log([at begin x=1, y=2, z=3, []]) 
Logger.log([arguments now:, []]) 
Logger.log([arguments[0]=a, []]) 
Logger.log([arguments[1]=b, []]) 
Logger.log([arguments[2]=c, []]) 
Logger.log([at end x=a, y=b, z=c, []]) 

因此,参数X,Y,Z只改变,当最初指定他们。在第一种情况下(不带参数调用argtest),即使在给参数赋值之后它们仍然未定义。那么为了使它工作而缺少什么呢?请注意,我不想触摸x,y,z。相反,在最后的实现中,我想将参数传递给一个对它们有效的函数。

+0

目前,您正在成功更改'arguments [n]',但它不会影响'x','y'或'z'。为什么不使用'arguments [n]'表示法来引用'x','y','z'? – LarsH

+0

这是什么浏览器?即使在没有参数的情况下调用函数,我也可以为'arguments'赋值。这是在Chrome中。 –

+0

@LarsH嗯。如果在调用函数(第二次调用argtest)时指定了x,y和z,只需更改参数[0..2]即可,即使未指定它们, 'atest()') – pbhd

回答

1

的问题是,调用argtest()时,arguments实际上并没有一个"0"属性引用x,或"1"y等:

argtest()  => arguments = { "length": 0 } 
argtest(1,2,3) => arguments = { "length": 3, "0": x, "1": y, "2": z } 

该引用的定义中描述步骤11.cES5 10.6,它为每个“索引”arguments定义了getter和setter,但受限于named的参数个数和参数个数。

关于你的意图:

我想在函数的开始到投入到现有的实现的功能,只是需要的参数和一些默认的参数,例如通话defaults (arguments, "string=nana", "number=4")

您可能会发现像这样简单:

function argTest(x, y, z) { 
    x = typeof x !== 'undefined' ? x : ...; 
    y = typeof y !== 'undefined' ? y : ...; 
    // etc. 
} 

你想要做什么是可能的ES5,但将意味着定义与getter和setter方法为自己的“论据”对象每个“指标”而得名的说法,是否通过值或不正确,通过Object.create/Object.definePropertiesget/set - 而且,我不会考虑这个“简单”:

function argtest(x, y, z) { 
    defaults({ 
     length: argtest.length, 

     get '0'() { return x; }, 
     set '0'(val) { x = val; }, 

     get '1'() { return y; }, 
     set '1'(val) { y = val; }, 

     get '2'() { return z; }, 
     set '2'(val) { z = val; } 
    }, ...); 

    // ... 
} 
+0

感谢您的解释,这个工程,但是,呵呵,是的,这并不简单。我认为参数对象以某种方式与参数的黑魔法相关,但它反映了当前传递的参数。所以现在我知道更好。 Wer nicht fragt bleibt dumm。 – pbhd

0

arguments[0]="a"; 
arguments[1]="b"; 
arguments[2]="c"; 

后你为什么不加

x = arguments[0]; 
y = arguments[1]; 
z = arguments[2]; 

? 我想有一些理由不能达到你的目标,但我想我需要一个更现实的例子来看看真正能达到你的目标。

+0

那么,我可以只使用x,y,z参数列表。我想在函数开头的现有实现中调用一个函数,该函数只需将参数和一些默认值作为参数,例如'defaults(arguments,“string = nana”,“number = 4”)',因此指定实际参数的名称会以某种方式增加不必要的开销。 – pbhd

0

也许你可以做这样的事情:

var args = Array.prototype.slice.call(arguments); 

然后用args工作?你可以通过args到你需要的其他功能。让我知道,如果这可以帮助你,或者如果我吠叫错误的树。