在构造函数之后运行其他操作

时间:2013-09-27 10:12:13

标签: javascript

是否可以更改构造函数,以便在创建对象后运行一些额外的操作。我试过像:

var origFoo = Foo
Foo = function() {
    origFoo.apply(this, arguments);
    /* extra actions */
}
Foo.prototype = new origFoo();

但是这有几个问题,例如构造函数被运行两次或更改原型链。

1 个答案:

答案 0 :(得分:3)

你非常接近。您应该将Foo.prototype分配给origFoo.prototype以获得相同的原型链。其他一切都在现场!

示例:

var Foo = function () {
    console.log('OriginalFoo');
};

Foo.prototype.method1 = function () {
    console.log('Method1');
};

OriginalFoo = Foo;

Foo = function () {
    OriginalFoo.apply(this, arguments);
    console.log('NewFoo');
};

Foo.prototype = OriginalFoo.prototype;

Foo.prototype.method2 = function () {
    console.log('Method2');
};

var x = new Foo();

x.method1();
x.method2();

演示:http://jsbin.com/ibatah/1/edit?js,console,output

PS:仍然存在类似静态属性的问题(Foo.prop),但我担心除了一次复制一个之外我没有解决方案。

编辑:特殊构造函数的解决方案。

确实有一些构造函数不喜欢被称为函数ex:Image。为了克服它,你可以在下面做更多的awkard解决方案。您可以利用以下事实:您可以从构造函数返回一个对象,它取代了使用new创建的对象。在重写的构造函数中,在调用方法而不是this时必须始终使用此新对象。

var Foo = function(a,b,c) {
  console.log('OriginalFoo',a,b,c);
};
Foo.prototype.prop1 = 'Property1';
Foo.prototype.method1 = function() {
  console.log('Method1', this.prop1);
};


OriginalFoo = Foo;
Foo = function(a,b,c) {
  var obj = new OriginalFoo(a,b,c);

  obj.init('Changed...'); // or this.init.call(obj,'Changed!'); 
  this.init('Not Changed'); // applies to a discarded object, has no effect

  console.log('NewFoo');
  return obj;
};

Foo.prototype = OriginalFoo.prototype;

Foo.prototype.prop2 = 'Property2';

Foo.prototype.method2 = function() {
  console.log('Method2', this.prop2);
};
Foo.prototype.init = function(param) {
  this.prop2 = param;
};



var x = new Foo('1','2','3');
console.log(x.prop1);
console.log(x.prop2);
x.method1();
x.method2();

演示:http://jsbin.com/ibatah/2/edit?js,console,output