首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >javascript应用于构造函数,抛出“格式错误的形式参数”

javascript应用于构造函数,抛出“格式错误的形式参数”
EN

Stack Overflow用户
提问于 2009-12-24 18:04:08
回答 4查看 6.1K关注 0票数 24

感谢对this question的出色响应,我理解了如何使用varargs调用javascript函数。

现在,我希望将应用与构造函数结合使用

我发现了一些有趣的信息,on this post

但是我的代码正在抛出错误

尝试1:

代码语言:javascript
运行
复制
var mid_parser = new Parser.apply(null, mid_patterns);

错误:

代码语言:javascript
运行
复制
TypeError: Function.prototype.apply called on incompatible [object Object]

尝试2:尝试1:

代码语言:javascript
运行
复制
var mid_parser = new Parser.prototype.apply(null, mid_patterns);

错误:

代码语言:javascript
运行
复制
TypeError: Function.prototype.apply called on incompatible [object Object]

企图2:

代码语言:javascript
运行
复制
function Parser()
{
    this.comparemanager = new CompareManager(arguments);
}

mid_patterns = [objA,objB,objC]
var mid_parser = new Parser();
Parser.constructor.apply(mid_parser, mid_patterns);

错误:

代码语言:javascript
运行
复制
syntax_model.js:91: SyntaxError: malformed formal parameter

企图3:

代码语言:javascript
运行
复制
var mid_parser = Parser.apply(null, mid_patterns);

错误:

代码语言:javascript
运行
复制
TypeError: this.init is undefined // init is a function of Parser.prototype

我现在有个解决办法:

代码语言:javascript
运行
复制
function Parser()
{
    if(arguments.length) this.init.call(this,arguments); // call init only if arguments
}
Parser.prototype = {
   //...
   init: function()
   {
         this.comparemanager = new CompareManager(arguments);
   }
   //...
}

var normal parser = new Parser(objA,objB,objC);

mid_patterns = [objA,objB,objC]
var dyn_parser = new Parser();
dyn_parser.init.apply(dyn_parser, mid_patterns);

这是很好的工作,但它不是像我想的那样干净和普遍。

在javascript中可以用varargs调用构造函数吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-12-24 18:13:05

您可以使用apply并传递一个空对象作为this参数:

代码语言:javascript
运行
复制
var mid_parser = {};
Parser.apply(mid_parser, mid_patterns);

但是这个解决方案不会照顾到原型链。

您可以使用Parser运算符创建一个new对象,但不需要传递参数,然后使用apply重新运行构造函数:

代码语言:javascript
运行
复制
var mid_parser = new Parser();
Parser.apply(mid_parser, mid_patterns);
票数 17
EN

Stack Overflow用户

发布于 2010-10-25 23:22:18

更好的解决方案是创建一个临时构造函数,应用所需类的原型(以确保prototype链被保留),然后手动应用构造函数。这可以防止不必要地调用构造函数两次.

代码语言:javascript
运行
复制
applySecond = function(){
    function tempCtor() {};
    return function(ctor, args){
        tempCtor.prototype = ctor.prototype;
        var instance = new tempCtor();
        ctor.apply(instance,args);
        return instance;
    }
}();

我测试了性能,发现在非常简单的情况下,这个方法实际上要慢一点。但是,它只需要在构造函数中构造一个Date()对象,这样才能提高效率。另外,不要忘记,如果没有传递参数,一些构造函数可能会抛出异常,因此这也是更正确的。

我的验证代码:

代码语言:javascript
运行
复制
var ExpensiveClass = function(arg0,arg1){
    this.arg0 = arg0;
    this.arg1 = arg1;
    this.dat = new Date();
}

var CheapClass = function(arg0,arg1){
    this.arg0 = arg0;
    this.arg1 = arg1;
}

applyFirst = function(ctor, args){
    var instance = new ctor();
    ctor.apply(instance, args);
    return instance;
}

applySecond = function(){
    function tempCtor() {};
    return function(ctor, args){
        tempCtor.prototype = ctor.prototype;
        var instance = new tempCtor();
        ctor.apply(instance,args);
        return instance;
    }
}();

console.time('first Expensive');
for(var i = 0; i < 10000; i++){
    test = applyFirst(ExpensiveClass ,['arg0','arg1']);
}
console.timeEnd('first Expensive');

console.time('second Expensive');
for(var i = 0; i < 10000; i++){
    test = applySecond(ExpensiveClass ,['arg0','arg1']);
}
console.timeEnd('second Expensive');

console.time('first Cheap');
for(var i = 0; i < 10000; i++){
    test = applyFirst(CheapClass,['arg0','arg1']);
}
console.timeEnd('first Cheap');

console.time('second Cheap');
for(var i = 0; i < 10000; i++){
    test = applySecond(CheapClass,['arg0','arg1']);
}
console.timeEnd('second Cheap');

结果:

代码语言:javascript
运行
复制
first Expensive: 76ms
second Expensive: 66ms
first Cheap: 52ms
second Cheap: 52ms
票数 11
EN

Stack Overflow用户

发布于 2010-01-28 12:34:43

您可以利用这样一个事实:您可以使用apply(...)链接构造函数来实现这一点,尽管这需要创建一个代理类。下面的construct()函数允许您执行以下操作:

代码语言:javascript
运行
复制
var f1 = construct(Foo, [2, 3]);
// which is more or less equivalent to
var f2 = new Foo(2, 3);

construct()函数:

代码语言:javascript
运行
复制
function construct(klass, args) {

  function F() {
    return klass.apply(this, arguments[0]); 
  }; 

  F.prototype = klass.prototype; 

  return new F(args);

}

使用它的一些示例代码:

代码语言:javascript
运行
复制
function Foo(a, b) {
  this.a = a; this.b = b;
}

Foo.prototype.dump = function() {
  console.log("a = ", this.a);
  console.log("b = ", this.b);
};

var f = construct(Foo, [7, 9]);

f.dump();
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1959247

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档