Are there problems with replacing a Javascript constructor's .prototype rather than adding to it?

雨燕双飞 提交于 2019-12-13 14:27:42

问题


I've come across another developer's code which does something like this to define a Javascript type:

function Ninja() {}
Ninja.prototype = {
  swingSword: function(){
    return true;
  }
}

when the more conventional manner is something like:

function Ninja() {}
Ninja.prototype.swingSword = function() {
    return true;
}

The first form mostly works, in that you can create a new instance and call the swingSword method, and instanceof is accurate:

var ninja = new Ninja();
ninja.swingSword(); // returns true
ninja instanceof Ninja; // also true

However, ninja.constructor points to Object rather than the Ninja function. This is an issue for me: I'm trying to access the constructor via an instance, as a workaround for the constructor not being exposed in any other way. But apart from accessing the constructor attribute for reflection/workaround hacks, does the first form cause any significant issues?

Are there any other important attributes of the original Ninja.prototype which might be getting hidden? Will the first form cause any issues with inheriting types, or common libraries?

I'm trying to figure out if this an unusual but acceptable Javascript pattern, or actually a common Javascript misstep or "gotcha" and should be considered a bug.

Note my Ninja example is based on some example code from a tutorial by John Resig. The actual type in question is not called Ninja, and is longer and more complicated.

Also, I've read this guide to constructors and prototypes and understand, eg how prototypes are used in attribute lookups and why isinstanceof still works.


回答1:


When you "inherit" from another prototype you usually replace the entire prototype, if constructor is important you can re set it to the "correct" value:

var Child = function(){};
//"inherit" from Parent
Child.prototype=Object.create(Parent.prototype);
//reset the constructor
Child.prototype.constructor = Child;

So in your case just repair the constructor after you set the prototype:

var Ninja = function() {}
Ninja.prototype = {
  swingSword: function(){
    return true;
  }
};
// you can put the next line anywhere you want to fix the problem
// http://stackoverflow.com/a/16063711/1641941 under this.constructor
Ninja.prototype.constructor=Ninja;

Or:

var Ninja = function() {}
Ninja.prototype = {
  swingSword: function(){
    return true;
  },
  constructor:Ninja
};


来源:https://stackoverflow.com/questions/19782315/are-there-problems-with-replacing-a-javascript-constructors-prototype-rather-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!