如何重命名原型?

时间:2014-04-29 07:56:28

标签: javascript

我从Angular的DB中获取了一个promise对象。

当我调用myObj instanceof CustomObject时,我希望此对象返回true,但不修改promise comportment。

我写的那一刻:

function CustomObject(myExistingPromise) {
   this.obj = myExistingPromise;
};

但要操纵我的承诺,我需要(new CustomObject(myExistingPromise)).obj代替new CustomObject(myExistingPromise)

有办法吗?

2 个答案:

答案 0 :(得分:2)

TL; DR - 改为使用duck typing;在对象或某物上粘贴属性并使用它而不是instanceof CustomObject。你可以在最先进的浏览器中做你想做的事情,或者至少接近,但它真的很难看。

完整的monty:

instanceof基本上遍历对象的原型链,并将链中的每个条目与您引用的函数的prototype属性进行比较(例如,obj instanceof CustomObject搜索原型链obj寻找CustomObject.prototype)。

因此,为了追溯使instanceof为真,您必须将CustomObject.prototype插入对象的原型链中。

您目前无法在标准范围内执行此操作;没有办法设置现有对象的原型。在ES5中,您可以通过getPrototypeOf 获取原型,但是设置它需要setPrototypeOf,这将是ES6(最前沿)现代浏览器的版本已经拥有它 - IE11 +,Firefox 31 +,Chrome 34+; chart)。

但这样做真的很难看并且有很大的副作用。

基本上,你要做的是插入CustomObject.prototype作为promise的基本原型的原型(链中的Object.prototype之上的原型)。这意味着由与承诺相同的构造函数创建的所有对象也将神奇地变为instanceof CustomObject,而不仅仅是我们所采取的行为。这真的不是一个好主意,但如果你真的想这样做,下面就有一个例子。

要仅影响对象的一个​​实例,您可能不会这样做,但您可以接近。您可以为对象提供基于CustomObject.prototype的新原型,并复制其可以看到的原始原型的所有属性(例如,可枚举的)。问题是A)也许该原型具有重要的非可枚举属性,并且B)这将使其不再instanceof其原始构造函数(因为原始构造函数的原型不再在链中)。 (B)可能是也可能不是问题(大多数人使用鸭子打字,而不是instanceof),但(A)会使解决方案相当脆弱。

底线:我建议找一种不同的方式,而不是要求对象为instanceof CustomObject。在其上放置标记属性。


CustomObject.prototype注入对象原型链的基础,将影响原始对象的构造函数创建的所有对象(关键位为{{ 1}}功能)

monkeyPatchConstructorPrototype

Live Example (仅适用于尖端浏览器,请参阅上面的注释和图表链接)

输出:

Before:

obj instanceof Original? true

obj instanceof InsertMe? false

After:

obj instanceof Original? true

obj instanceof InsertMe? true

Previously-created objects are also affected:

obj2 instanceof Original? true

obj2 instanceof InsertMe? true

As are ones created afterward:

obj3 instanceof Original? true

obj3 instanceof InsertMe? true

答案 1 :(得分:1)

那是垃圾,因为你可以很容易地实现我写的相同。与

var CustomObject=angular constructor, or
var CustomObject=obj.constructor;

首先生成一次obj而不是添加这个如果你不知道构造函数...现在你可以在Angular构造函数上生成一个新的CustomObject。

function CustomObject (Angularvalue1, Angularvalue2, .....)
  {
  CustomObject.constructor.call (this,Angularvalue1, Angularvalue2, .....);
  }

CustomObject.constructor=obj.constructor; // if you know the constructor of Angluar   replace obj.constructor with the angular obj constructor function
CustomObject.prototype=obj.constructor.prototype;
CustomObject.prototype.constructor=CustomObject; //---this line would change also the constructor property of the angular constructor, remove it

var myObject=new CustomObject (Angularvalue1, Angularvalue2, .....)