为什么我的参数数组只有1?

时间:2013-05-29 19:21:45

标签: javascript

为什么my_game.size()返回1的大小?我认为来自make_game的论据会插入到game中,因此arguments.length将为3,但显然不是。这是什么原因?

function game()
{
    var args = arguments;
    this.size = function() { return args.length; };
}

function make_game()
{
    return new game(arguments);
}

var my_game = make_game(4, 'a', true);

console.log(my_game.size()); // 1

5 个答案:

答案 0 :(得分:6)

您将整个arguments对象作为单个参数传递

如果要将其中的每个参数作为单独的参数传递,则必须明确地这样做:

return new game(arguments[0], arguments[1], arguments[2]);

如果您没有使用构造函数,则可以使用apply method

return game.apply(this, arguments); 

...但是既然你会得到这个结果:

Uncaught TypeError: function apply() { [native code] } is not a constructor 

...因为它尝试使用apply作为构造函数而不是game

答案 1 :(得分:4)

当您在game(arguments)内执行make_game()时,您使用单个参数调用game(),该参数是传递给make_game()的参数数组。

如果你想分别传递每个参数,你通常会使用game.apply(arguments),但为了让它与new一起正常工作,它会变得更加复杂:

function make_game()
{
    return new (Function.prototype.bind.apply(game, arguments));
}

This answer详细解释了此方法的工作原理。

答案 2 :(得分:3)

return new game(arguments);

您传入的是arguments对象,只传递一个对象。这是一个论点。

要将参数转发给普通函数,您可以使用apply:

var fn = function() {
  otherFn.apply(null, arguments);
};

但这有两件事,它在arguments数组中传递以用作参数,但它也设置执行上下文(this的值)。但是构造函数会创建它自己的值。这提出了一个问题......


在普通的JS中,将参数转发给构造函数要复杂得多。在Coffee脚本中,它很容易,但它编译成一些疯狂的JS。 See here

诀窍似乎是使用no-op构造函数创建一个新的子类,并手动调用构造函数。

var newConstructor = function() {}; // no-op constructor
newConstructor.prototype = Game.prototype; // inherit from Game
var child = new newConstructor(); // instantiate no-op constructor
var result = Game.apply(child, arguments); // invoke real constructor.

但那很毛茸茸。也许你应该重新考虑你的方法。

答案 3 :(得分:1)

您只将一个参数传递给构造函数,它是arguments

更改

var args = arguments;

var args = arguments[0];

答案 4 :(得分:0)

只是因为你只传递了一个论点。

function game()
{
    var args = arguments;
    this.size = function() { return args.length; };
}

function make_game()
{
    return new game(arguments); // passing only one
}

function make_game2()
{
    return new game(arguments[0], arguments[1], arguments[2]); // passing three 
}

var my_game = make_game(4, 'a', true);

console.log(my_game.size()); // 1


var my_game2 = make_game2(4, 'a', true);

console.log(my_game2.size()); // 3

您可以使用其他函数初始化对象

function game()
{
    var args;
    this.size = function() { return args.length; };
    this.init = function(){
        args = arguments;
    }
}

function make_game()
{
    var gm =  new game(); 
    gm.init.apply(gm, arguments);
    return gm;
}


var my_game = make_game(4, 'a', true);

console.log(my_game.size()); // 3

这是为了演示它是如何工作的。强烈建议遵循基于原型的设计。