Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
129 views
in Technique[技术] by (71.8m points)

javascript - this.constructor.prototype -- can't wholly overwrite, but can write individual props?

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(){};
}

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?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

You can, but it's too late. The new instance has already been generated, inheriting from the old prototype. Maybe read how new works.

I don't like how prototypes are usually defined externally from a constructor.

That's just the way it is. You really should not setup the prototype from within the constructor - it would be executed everytime a new instance is created. That's specifically what prototypes are not supposed to be. See also Assigning prototype methods *inside* the constructor function - why not?

and want to logically encapsulate things better.

You might want to have a look at the various (revealing) module patterns. Or maybe even at some Class framework.

I'm currently looking for more concrete reasons that I should not go forth with the pattern I've been presenting.

It does not work in Internet Explorer. It would not work in any ES5-compliant environment that does not support the __proto__ property. You should never use it set a prototype on an existing object. Instead, use Object.create (or its shim) for Correct javascript inheritance - which requires that you overwrite the prototype outside of the constructor.

My suggestion is to call your extend helper outside the constructor on it, which still has a nice syntax.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...