覆盖 Javascript 中的方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15497259/
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-27 00:59:44  来源:igfitidea点击:

Overriding methods in Javascript

javascriptprototypeoverriding

提问by codingsplash

I would like to know what is the difference between overriding methods with prototypes and without prototypes. Consider:

我想知道有原型和没有原型的覆盖方法有什么区别。考虑:

Example 1:

示例 1:

function Animal() {
    this.sleep = function () {
        alert("animal sleeping");
    };

    this.eat = function () {
        alert("animal eating");
    };
}

function Dog() {
    this.eat = function () {
        alert("Dog eating");
    };
}

Dog.prototype = new Animal;

var dog = new Dog;

dog.eat();

Example 2:

示例 2:

function Animal() { }

function Dog() { }

Animal.prototype.sleep = function () {
    alert("animal sleeping");
};

Animal.prototype.eat = function () {
    alert("animal eating");
};

Dog.prototype = new Animal;

Dog.prototype.eat = function () {
    alert("Dog eating");
};

var dog = new Dog;

dog.eat();

I feel both examples produce the same effect that the Dogclass is overriding the eat method of the Animalclass. Or is there anything different happening?

我觉得这两个例子产生了相同的效果,即Dog该类覆盖了该类的 Eat 方法Animal。或者有什么不同的事情发生?

采纳答案by Arun P Johny

In the first method each of the Animalinstance will get its own implementation of sleepand eatmethods.

在第一个方法中,每个Animal实例都将获得自己的sleepeat方法的实现。

While in the second model All instances will share the same instance of the sleepand eatmethods.

而在第二个模型中,所有实例将共享sleepeat方法的相同实例。

The second model is better since we can share the methods.

第二个模型更好,因为我们可以共享方法。

回答by Aadit M Shah

As Arun mentioned in the first example you're creating sleepand eatfunctions for each new instance. In the second example there's only one sleepand eatfunction which is shared amongst all the instances.

正如 Arun 在第一个示例中提到的,您正在为每个新实例创建sleepeat运行。在第二个示例中,只有一个sleepandeat函数在所有实例之间共享。

In this case the second method is better, but it's good to know when to use the first method and when to use the second. A little bit of theory first:

在这种情况下,第二种方法更好,但最好知道何时使用第一种方法以及何时使用第二种方法。先说一点理论:

Note:There are four kinds of variables in JavaScript - private, public, sharedand static.

注意:有四种类型的变量在JavaScript中- ,,和。privatepublicsharedstatic

Private variables are inaccessible outside of the function in which they are defined. For example:

私有变量在定义它们的函数之外是不可访问的。例如:

function f() {
    var x; // this is a private variable
}

Public variables are defined on the thisobject inside a function. For example:

公共变量this在函数内的对象上定义。例如:

function f() {
    this.x; // this is a public variable
}

Shared variables are shared on the prototypeof the function. For example:

共享变量prototype在函数上共享。例如:

function f() {}

f.prototype.x; // this is a shared variable

Static variables are properties of the function itself. For example:

静态变量是函数本身的属性。例如:

function f() {}

f.x; // this is a static variable

Most often it's best to declare the methods of a constructor function as shared methods since all instances of the constructor share them. However if your method needs to access a private variable then it must be declared as a public method itself.

大多数情况下,最好将构造函数的方法声明为共享方法,因为构造函数的所有实例都共享它们。但是,如果您的方法需要访问私有变量,则必须将其声明为公共方法本身。

Note:This is my own nomenclature. Not many JavaScript programmers adhere to it. Others seem to follow Douglas Crockford's nomenclature: http://javascript.crockford.com/private.html

注意:这是我自己的命名法。没有多少 JavaScript 程序员坚持它。其他人似乎遵循道格拉斯·克罗克福德的命名法:http: //javascript.crockford.com/private.html

To know more about prototypal inheritance in JavaScript read the following answer: https://stackoverflow.com/a/8096017/783743

要了解有关 JavaScript 中原型继承的更多信息,请阅读以下答案:https: //stackoverflow.com/a/8096017/783743

回答by happyCoda

In your first example each new Doginstance will have it's own eatmethod and in the second example there will be only one eatmethod on Dog.prototype, which will be shared between all future instances of Doglike Arun mentioned.

在您的第一个示例中,每个新Dog实例都有自己的eat方法,而在第二个示例中,将只有一个eat方法 on Dog.prototype,它将在DogArun 提到的所有未来实例之间共享。

This is the only "tricky"difference between those two. But it's always better to define methods on the prototypeto avoid high memory consumption and leaks.

这是两者之间唯一的“棘手”区别。但是最好在 上定义方法prototype以避免高内存消耗和泄漏。

回答by fardjad

The methods in first example are defined in object instance.

第一个示例中的方法在对象实例中定义。

You're setting the Dogprototype to a new Animalinstance, thus Dogwill inherit sleepand eatfunctions from Animal. Then you're DEFINING(NOT OVERRIDING) eatmethod in Dogconstructor as an instance method, and this will HIDEthe inherited eatmethod in Doginstances.

你的设置Dog原型到一个新的Animal实例,从而Dog将继承sleepeat功能的Animal。然后你在构造函数中定义(NOT OVERRIDINGeat方法Dog作为实例方法,这将隐藏实例中的继承eat方法Dog

Consider the following example:

考虑以下示例:

function LittleDog() { }
LittleDog.prototype = Object.create(Dog.prototype);
(new LittleDog()).eat();

The code above will alert animal eatingwith your code in first example.

上面的代码将animal eating在第一个示例中使用您的代码发出警报。

And will alert Dog eatingwith the code in the second one.

并会Dog eating用第二个中的代码发出警报。