this.constructor.prototype - 不能完全覆盖,但可以写个别道具吗?

Cha*_*kal 1 javascript

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

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

我发现我期望工作的一条神奇的线路没有.

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(){};
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,我可以编写单独的属性this.constructor.prototype,但是我不能像构造函数定义之外那样覆盖整个原型对象.

所以像这样的东西工作:

  this.constructor.prototype.exhaust = standardOrifice.exhaust;
  this.constructor.prototype.ingest = standardOrifice.ingest;
Run Code Online (Sandbox Code Playgroud)

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

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;
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

值得庆幸的是,到目前为止,在我的测试中,这种技术似乎运行良好,但我不确定是否存在我可能遗漏的细节或性能案例.

function Sphincter(){
  extend(this.constructor.prototype).from(standardOrifice);
  //...
}
Run Code Online (Sandbox Code Playgroud)

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

Ber*_*rgi 5

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

你可以,但为时已晚.新实例已经生成,继承自旧原型.也许阅读如何new运作.

我不喜欢原型通常是从​​构造函数外部定义的.

就是那样子.你真的不应该在构造函数中设置原型 - 它会在每次创建新实例时执行.这就是原型不应该是什么.另请参阅在构造函数内部分配原型方法* - 为什么不呢?

并希望在逻辑上更好地封装事物.

您可能希望了解各种(显示)模块模式.或者甚至可能在某个Class框架上.

我目前正在寻找更具体的理由,我不应该以我一直呈现的模式出发.

它在Internet Explorer中不起作用.它不适用于任何不支持该__proto__属性的ES5兼容环境.你永远不应该使用它在现有对象上设置原型.相反,使用Object.create(或其垫片)进行正确的javascript继承 - 这要求您在构造函数之外覆盖原型.

我的建议是打电话给你的extend助手的构造函数外就可以了,仍然有一个很好的语法.