Fir*_*row 24 javascript constructor variadic-functions
感谢对这个问题的精彩回答,我理解如何用varargs调用javascript函数.
现在我正在寻找使用构造函数的应用程序
我在这篇文章中找到了一些有趣的信息.
但我的代码是错误的
尝试1:
var mid_parser = new Parser.apply(null, mid_patterns);
Run Code Online (Sandbox Code Playgroud)
错误:
TypeError: Function.prototype.apply called on incompatible [object Object]
Run Code Online (Sandbox Code Playgroud)
尝试2:尝试1:
var mid_parser = new Parser.prototype.apply(null, mid_patterns);
Run Code Online (Sandbox Code Playgroud)
错误:
TypeError: Function.prototype.apply called on incompatible [object Object]
Run Code Online (Sandbox Code Playgroud)
尝试2:
function Parser()
{
this.comparemanager = new CompareManager(arguments);
}
mid_patterns = [objA,objB,objC]
var mid_parser = new Parser();
Parser.constructor.apply(mid_parser, mid_patterns);
Run Code Online (Sandbox Code Playgroud)
错误:
syntax_model.js:91: SyntaxError: malformed formal parameter
Run Code Online (Sandbox Code Playgroud)
尝试3:
var mid_parser = Parser.apply(null, mid_patterns);
Run Code Online (Sandbox Code Playgroud)
错误:
TypeError: this.init is undefined // init is a function of Parser.prototype
Run Code Online (Sandbox Code Playgroud)
我暂时有一个解决方法:
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);
Run Code Online (Sandbox Code Playgroud)
这很好用,但它并不像我想的那样干净和普遍.
是否可以在javascript中使用varargs调用构造函数?
CMS*_*CMS 17
您可以使用apply并传递一个空对象作为this参数:
var mid_parser = {};
Parser.apply(mid_parser, mid_patterns);
Run Code Online (Sandbox Code Playgroud)
但该解决方案不会关注原型链.
您可以Parser使用new运算符创建一个对象,但不传递参数,然后使用apply重新运行构造函数:
var mid_parser = new Parser();
Parser.apply(mid_parser, mid_patterns);
Run Code Online (Sandbox Code Playgroud)
jor*_*aul 11
更好的解决方案是创建临时构造函数,应用所需类的原型(以确保保留原型链),然后手动应用构造函数.这可以防止不必要地两次调用构造函数......
applySecond = function(){
function tempCtor() {};
return function(ctor, args){
tempCtor.prototype = ctor.prototype;
var instance = new tempCtor();
ctor.apply(instance,args);
return instance;
}
}();
Run Code Online (Sandbox Code Playgroud)
我测试了性能,发现这种方法在非常简单的情况下实际上有点慢.但是,它只需要在构造函数中构造单个Date()对象,以提高效率.另外,不要忘记,如果没有传递参数,某些构造函数可能会抛出异常,因此这也更正确.
我的验证码:
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');
Run Code Online (Sandbox Code Playgroud)
结果:
first Expensive: 76ms
second Expensive: 66ms
first Cheap: 52ms
second Cheap: 52ms
Run Code Online (Sandbox Code Playgroud)
您可以利用链接构造函数apply(...)来实现此目的,尽管这需要创建代理类.以下construct()功能可让您:
var f1 = construct(Foo, [2, 3]);
// which is more or less equivalent to
var f2 = new Foo(2, 3);
Run Code Online (Sandbox Code Playgroud)
该construct()函数:
function construct(klass, args) {
function F() {
return klass.apply(this, arguments[0]);
};
F.prototype = klass.prototype;
return new F(args);
}
Run Code Online (Sandbox Code Playgroud)
一些使用它的示例代码:
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();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5984 次 |
| 最近记录: |