Javascript:覆盖函数的原型 - 不好的做法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12260375/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 15:44:15  来源:igfitidea点击:

Javascript: Overwriting function's prototype - bad practice?

javascriptconstructorprototype

提问by Vitaly

Since when we declare a function we get its prototype's constructor property point to the function itself, is it a bad practice to overwrite function's prototype like so:

因为当我们声明一个函数时,我们将其原型的构造函数属性指向函数本身,所以像这样覆盖函数的原型是一种不好的做法:

function LolCat() {
}

// at this point LolCat.prototype.constructor === LolCat

LolCat.prototype = {
    hello: function () {
        alert('meow!');
    }
    // other method declarations go here as well
};

// But now LolCat.prototype.constructor no longer points to LolCat function itself

var cat = new LolCat();

cat.hello(); // alerts 'meow!', as expected

cat instanceof LolCat // returns true, as expected

This is not how I do it, I still prefer the following approach

这不是我的做法,我还是更喜欢下面的方法

LolCat.prototype.hello = function () { ... }

but I often see other people doing this.

但我经常看到其他人这样做。

So are there any implications or drawbacks by removing the constructor reference from the prototype by overwriting the function's prototype object for the sake of convenience as in the first example?

那么,为了方便起见,如第一个示例中那样,通过覆盖函数的原型对象来从原型中删除构造函数引用是否有任何影响或缺点?

采纳答案by Robin Winslow

I can't see anyone mentioning best practice as far as this is concerned, so I think it comes down to whether you can see the constructorproperty ever being useful.

就这一点而言,我看不到任何人提到最佳实践,所以我认为这归结为您是否可以看到该constructor属性有用。

One thing worth noting is that the constructorproperty, if you don't destroy it, will be available on the created object too. It seems to me like that could be useful:

值得注意的一件事是constructor,如果不销毁该属性,它也将在创建的对象上可用。在我看来,这可能很有用:

var ClassOne = function() {alert("created one");}
var ClassTwo = function() {alert("created two");}

ClassOne.prototype.aProperty = "hello world"; // preserve constructor
ClassTwo.prototype = {aProperty: "hello world"}; // destroy constructor

var objectOne = new ClassOne(); // alerts "created one"
var objectTwo = new ClassTwo(); // alerts "created two"

objectOne.constructor(); // alerts "created one" again
objectTwo.constructor(); // creates and returns an empty object instance

So it seems to me that it's an architectural decision. Do you want to allow a created object to re-call its constructor after it's instantiated? If so preserve it. If not, destroy it.

所以在我看来,这是一个架构决定。是否允许创建的对象在实例化后重新调用其构造函数?如果是这样保存它。如果没有,就销毁它。

Note that the constructor of objectTwo is now exactly equal to the standard Object constructor function - useless.

请注意, objectTwo 的构造函数现在完全等于标准的 Object 构造函数 - 无用。

objectTwo.constructor === Object; // true

So calling new objectTwo.constructor()is equivalent to new Object().

所以调用new objectTwo.constructor()等价于new Object().

回答by Asciiom

It's not bad practice but you have to know what you are doing and why. It is very useful for prototypal inheritance. The object of which you overwrite the prototype will get all the properties of the object you assign to it's prototype:

这不是坏习惯,但你必须知道你在做什么以及为什么。它对于原型继承非常有用。您覆盖原型的对象将获得您分配给它的原型的对象的所有属性:

You cause an object to inherit using

你导致一个对象继承使用

ChildClassName.prototype = new ParentClass();.

Now ChildClassName has all functionality of ParentClass but loses any functionality that was assigned to it's prototype before. You need to remember to reset the constructor property for the object using

现在 ChildClassName 拥有 ParentClass 的所有功能,但失去了之前分配给它的原型的任何功能。您需要记住使用重置对象的构造函数属性

ChildClassName.prototype.constructor=ChildClassName. 

Otherwise the object will be reported to be (when testing for the type of an object) of the ParentClass type instead of the ChildClassName type.

否则,对象将被报告为(在测试对象的类型时)是 ParentClass 类型而不是 ChildClassName 类型。

And now you can add more methods to the ChildClassName object in the way you described yourself.

现在您可以按照您自己描述的方式向 ChildClassName 对象添加更多方法。

ChildClassName.prototype.myMethod = function(){
    //do stuff
}

The result being a parent object/'class'(there are no real classes in javascript of course) and a child object/'class' that inherits from it and extends its functionality.

结果是一个父对象/“类”(当然,javascript 中没有真正的类)和一个从它继承并扩展其功能的子对象/“类”。

You just have to know that if you overwrite the prototype, any properties that where assigned to it will be gone. When constructing inheriting objects this might be exactly what you want.

您只需要知道,如果您覆盖原型,分配给它的任何属性都将消失。在构造继承对象时,这可能正是您想要的。

回答by Jeremy J Starcher

This form:

这种形式:

LolCat.prototype = {
  hello: function () {
      alert('meow!');
  }
};

Destroys any existing methods and public properties. In the example, as given, it doesn't matter as the newly created LolCat doesn't have any properties or methods. However, one should be mindful of this in more complicated code.

销毁任何现有的方法和公共属性。在示例中,正如给定的,这无关紧要,因为新创建的 LolCat 没有任何属性或方法。但是,在更复杂的代码中应该注意这一点。

This form:

这种形式:

LolCat.prototype.hello = function () { ... }

Adds a new method to an existing object and keeps the existing intact.

向现有对象添加新方法并保持现有对象不变。

回答by jAndy

Its not a bad practice to overwrite the constructorwhen using prototypal inheritance. Infact many people do it like so:

constructor在使用原型继承时覆盖 不是一个坏习惯。事实上,很多人都是这样做的:

LolCat.prototype = {
    constructor: LolCat,
    hello: function () {
        alert('meow!');
    }
};

回答by Somnath

Its not a bad practice. But there is a simple and standard way of overriding a function like below. When ever we define a 'function LolCat()' globally, its created under window so you can always code like below.

这不是一个坏习惯。但是有一种简单而标准的方法可以覆盖如下所示的函数。当我们全局定义一个“函数 LolCat()”时,它会在 window 下创建,因此您始终可以像下面这样编写代码。

window.LolCat = function() {...};
LolCat.prototype.hello = function () { ... }

回答by David

After many years of javascript, I stumbled upon a weird bug where a new instance of an object, then passed in a mixin had lost its __proto__when its prototypeclass were declared with :

经过多年的javascript,我偶然发现了一个奇怪的错误,其中一个对象的新实例,然后传入一个mixin,__proto__当它的prototype类声明为时丢失了它:

MyClass.prototype = {
   constructor: MyClass,
   myMethod(){ ...}
};

There is no anymore problem when using :

使用时不再有问题:

Object.assign( MyClass.prototype, {
   myMethod(){ ...}
});

Bonus : you don't have to reasign the construct anymore.

奖励:您不必再重新分配构造。

I guess it is because when we overwrite totally the prototype property, we wipe also its specials attributes and transform it as a normal one...maybe this one should not be writable by default...

我想这是因为当我们完全覆盖原型属性时,我们也会擦除它的特殊属性并将其转换为普通属性......也许默认情况下这个不应该是可写的......