2011-10-05 56 views
5

可能重复:
Use of .apply() with 'new' operator. Is this possible?使用应用与功能构造

我有5个或形式

var analyteSelection = new TemplatedSelectionContainer($('.analyte-container', this), helpers, optionsTemplate); 
var instrumentSelection = new AssetBackedSelection($('.instrument-container', this), helpers, optionsTemplate, Assets.instruments, 'Instrument'); 
var methodSelection = new AssetBackedSelection($('.method-container', this), helpers, optionsTemplate, Assets.methods, 'Method'); 

正如你所看到的6个变量赋值,一个这些构造函数的大部分非常相似。这将是很好,如果我可以创建一个小的通用钻营建设者,让我做一些事情,如:

var newSel = selectionContainerBuilder(this, helpers, optionsTemplate) 
var analyteSelection = newSel(TemplatedSelectionContainer, '.analyte-container'); 
var instrumentSelection = newSel(AssetBackedSelection, '.instrument-container', Assets.instruments, 'Instrument'); 
var methodSelection = newSel(AssetBackedSelection, '.method-container', Assets.methods, 'Method'); 

我能实现类似的东西与

var selectionContainerBuilder = function(ctx, helpers, optionsTemplate) { 
    return function(FuncDef, selector, a, b, c, d, e, f) { 
    return new FuncDef($(selector, ctx), helpers, optionsTemplate, a,b,c,d,e,f); 
    } 
} 

但严重的ICK。我希望能够将前三个已知参数拼接到参数数组的开头,并将其应用到FuncDef,但我被使用新运算符的需要所挫败。

而之前有人问,我不能做FuncDef内的新操作员执法,因为它是由coffeescript类关键字生成的。

回答

3

当然是可以做到的。这是eval证明有用的一种情况。

function newApply(cls, args) { 
    var argsAsString = []; 
    for (var i = 0, l = args.length; i < l; i++) { 
     argsAsString.push('args[' + i + ']'); 
    } 
    return eval('new cls(' + argsAsString.join(',') + ')'); 
} 

(从another thread被盗)

+0

噢,那是......好点的实际。嗯,不知道这是否有任何范围问题? –

+0

作用域不应该成为问题,因为'cls'和'args'在它们传递给'newApply'时将它们的作用域链与它们连接在一起。 – user123444555621

+0

我想知道为什么(a)你选择了这个答案,而不是从另一个问题和(b)中接受的答案,你没有投票决定把它作为一个副本来结束? –

2

恭喜!你刚刚发现了一个Javascript中最丑陋的秘密疣,你想做什么不能做

常见的解决方法要么创建包装函数(像你这样)或重组构造函数接收列表/对象,而不是大量的争论。


有一个提案“...”语法和谐多个参数(JS的下一个版本),但到那时就没有办法通过一个可变数量的参数到一个构造函数。

当你有很多参数时,传递一个列表或对象通常是一个好主意。它可以保护您不会因意外而弄乱订单,并且更容易处理可选参数(就像您的情况一样)。

new Foo("arg1", { 
    helpers: helpers, 
    options: optionsTemplate, 
    intruments: Assets.instruments 
}); 

编辑:刚刚发现这个同一主题的另一个问题是:Use of .apply() with 'new' operator. Is this possible?