为什么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
答案 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
这是为了演示它是如何工作的。强烈建议遵循基于原型的设计。