如何在构造函数调用之前欺骗instanceof运算符?

时间:2013-10-09 17:01:08

标签: javascript node.js constructor

我正在尝试重用node.js Buffer模块来在其上创建一个经过修改的缓冲区。问题是,如果我直接从它继承,我不能应用构造函数,并且一些属性会丢失(因为它们没有被初始化)。 EventEmitter上的用法按预期工作。

我担心问题在于if(!(this instanceof Buffer)){}代码,即评估为false,因为代码实际上并没有继承原型,所以我需要一种方法来欺骗instanceof运营商让它发挥作用。

我正在使用ES5 Class模块https://npmjs.org/package/es5class

var Class = require('es5class');

var MyBuffer = Class.define('MyBuffer').implement(Buffer, true);

// MyBuffer.prototype.write exists
// (new MyBuffer(4)).length is undefined
// (new MyBuffer(4)).parent is undefined, etc

EventEmitter正常工作

var Class = require('es5class');

var MyEventEmitter = Class.define('MyEventEmitter').implement(require('events').EventEmitter, true);

// MyEventEmitter.prototype.emit exists
// (new MyEventEmitter())._events is an object as expected

我正在尝试更改ES5类模块以使其正常工作,尝试在调用constructor之前覆盖f.apply(),但无济于事。

// $apply is an array of mixin'd classes, for example, Buffer or EventEmitter
self.$apply.forEach(function (f){
  var oldctor = instance.constructor; // current instance constructor

  Object.defineProperty(instance, 'constructor', {
    value       : f, // trying to change it
    writable    : true,
    configurable: true,
    enumerable  : false
  });

  console.log(instance instanceof f); // false, this needs to evaluate to true just before the f.apply, how to? instance.prototype cannot "redefine" prototype

  f.apply(instance, arguments); // works the same as EventEmitter.apply(this, arguments);

  Object.defineProperty(instance, 'constructor', {
    value       : oldctor, // try to restore it
    writable    : true,
    configurable: true,
    enumerable  : false
  });
});

管理用一个相当丑陋的黑客修复它,Bergi在https://github.com/pocesar/ES5-Class/blob/master/index.js#L24中指出

superApply = function(instance, object, args){
  if (object.$apply.length) {
    object.$apply.forEach(function (f){
      // dirty little hack to make classes like Buffer think the prototype is instanceof itself
      spo(instance, f.prototype);
      f.apply(instance, args);
    });
  }
},

0 个答案:

没有答案