2

为什么我返回的大小为 1 my_game.size()?我认为 from 的参数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
4

5 回答 5

6

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

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

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

如果你没有使用构造函数,那么你可以使用apply 方法

return game.apply(this, arguments); 

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

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

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

于 2013-05-29T19:24:16.310 回答
4

当您在game(arguments)内部make_game()进行调用时,您正在game()使用单个参数进行调用,该参数是传递给make_game().

如果你想分别传递每个参数,你通常会使用game.apply(arguments),但要让它正常工作,new它会变得有点复杂:

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

这个答案详细解释了这种方法的工作原理。

于 2013-05-29T19:29:54.997 回答
3
return new game(arguments);

您正在传递参数对象,只有一个对象。所以这是一个论点。

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

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

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


在纯 JS 中将参数转发给构造函数要复杂得多。在 Coffee 脚本中,这很容易,但它会编译成一些疯狂的 JS。 看这里

诀窍似乎是使用无操作构造函数创建一个新的子类,然后手动调用构造函数。

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.

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

于 2013-05-29T19:25:06.480 回答
1

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

改变

var args = arguments;

var args = arguments[0];
于 2013-05-29T19:23:46.053 回答
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

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

于 2013-05-29T19:31:27.510 回答