本文介绍了this.constructor.prototype - 不能完全覆盖,但可以写个别道具吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR? 为什么我不能在构造函数中覆盖构造函数的原型?

TL;DR? Why can't I overwrite a constructor's prototype from within the constructor?

我正在弄清楚我的原型继承模式。我不喜欢原型通常是如何从构造函数外部定义的,并希望在逻辑上更好地封装事物。

I'm figuring out my pattern for prototypical inheritance. I don't like how prototypes are usually defined externally from a constructor, and want to logically encapsulate things better.

我发现我期望工作的一条神奇的线条,不是。

I found that the one magical line that I expected to work, doesn't.

function Orifice(){
  this.exhaust=function(){};
  this.ingest=function(){};
}
var standardOrifice = new Orifice();

function Sphincter(){
  this.constructor.prototype = standardOrifice; // <-- does not work
  this.relax=function(){};
  this.tighten=function(){};
}

有趣的是,我可以将单个属性写入。 constructor.prototype ,但是我不能用构造函数定义之外的方式覆盖整个原型对象。

Interestingly, I can write individual properties to this.constructor.prototype, but I cannot overwrite the whole prototype object the same way one can outside of a constructor's definition.

所以像这样的东西工作:

So stuff like this works:

  this.constructor.prototype.exhaust = standardOrifice.exhaust;
  this.constructor.prototype.ingest = standardOrifice.ingest;

我可以创建一个简单的克隆函数来处理这个问题:

For which I can create a simple clone function to handle this:

function extend(target){
  return {
    from: function(obj){
      target.__proto__ = obj.constructor.prototype;
      for (key in obj) if (obj.hasOwnProperty(key)) target[key]=obj[key];
      return target;
    }
  };
}

值得庆幸的是,在我的测试中,到目前为止,这种技术出现运作良好,虽然我不确定是否有细节或性能案例我可能会丢失。

Thankfully in my tests so far, this technique appears to work well, though I'm not sure if there are details or performance cases I could be missing.

function Sphincter(){
  extend(this.constructor.prototype).from(standardOrifice);
  //...
}

为什么不能我从构造函数中覆盖构造函数的原型?但是我可以在构造函数之外吗?单独编写属性可以在构造函数中工作吗?

Why can't I overwrite a constructor's prototype from within the constructor? Yet I can outside the constructor? And writing properties individually works from within a constructor?

推荐答案

对特定问题的回答



Answer to the Specific Question

这是因为在对象已经被实例化之后,构造函数实际上被称为。并且由于您的对象已经设法在构造函数触及任何内容之前进行实例化,因此您的构造函数也已经被赋予了默认原型。

It's because constructors are actually called after your object has already been instantiated. And since your object has managed to instantiate before your constructor has touched anything, your constructor has also already been assigned a "default" prototype.

将属性添加到 this.constructor.prototype 似乎有效 - 因为你实际上正在操纵构造函数的预分配默认原型对象,所有实例都继承自该对象。

Adding properties to this.constructor.prototype seems to work -- because you're actually manipulating the constructor's pre-assigned default prototype object, which all of your instances inherit from.

在我的例子中, this.constructor.prototype 最终引用了默认分配的构造函数原型:所以完全覆盖它意味着从那一刻开始所有新实例会有新的原型 - 正如Bergi所说,太迟了 - 你当前的实例将没有那个新的原型,因为它仍然有旧的默认分配原型,因为它已经被实例化了。

In my examples, this.constructor.prototype ended up referring to the default-assigned prototype of the constructor: so wholly overwriting it meant all new instances from that moment onward would have that new prototype -- as Bergi said, "too late" -- your current instance would not have that new prototype, as it still has the old default-assigned prototype because it's already been instantiated.

我'我明白了,在我的问题中提出的技术根本不会这样做。问题本身通常是错误的。通过将Bergi的智慧与我个人的偏见相结合,我想出了这种模式,以避免必须完全找到原始问题的答案:

I've come to understand, that the techniques presented in my question simply won't do. The question itself is generally misguided. By combining Bergi's wisdom with my own personal biases, I've come up with this pattern as a means to avoid having to find an answer to the original question altogether:

function extend(p){
  return { to: function(C){ for (k in p) if (p.hasOwnProperty(k)) 
  C.prototype[k]=p[k]; return C; } };
};

var orifice = new function Orifice(){
  this.exhaust=function(){};
  this.ingest=function(){};
};

var Sphincter = extend(orifice).to(function Sphincter(){
  this.relax=function(){};
  this.tighten=function(){};
});









这是扩展函数,扩展:

function extend(parentObject){
  return { 
    to: function(ChildConstructor){
      for (key in parentObject) 
        if (parentObject.hasOwnProperty(key)) 
          ChildConstructor.prototype[key] = parentObject[key];
      return ChildConstructor;
    }
  };
};

我用它来测试它的工作原理:

// TESTING
var s=new Sphincter();
var tests=['relax','tighten','exhaust','ingest'];
for (var i in tests) console.log("s."+tests[i]+"() is "+(tests[i]in s?"present :)":"MISSING!"));

这篇关于this.constructor.prototype - 不能完全覆盖,但可以写个别道具吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 03:54