Javascript 中的原型关键字

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

Prototype keyword in Javascript

javascripthtml

提问by Tintin

What is prototypeproperty, and why is it necessary? So far, I have learnt that this provides public access to more intrinsic, and private prototypeof the object; is that correct?

什么是prototype财产,为什么有必要?到目前为止,我已经了解到这提供prototype了对对象更内在和私有的公共访问;那是对的吗?

Also, what's the difference between following statements?

另外,以下语句之间有什么区别?

MyConstructor.age = 30;
MyConstructor.prototype.age = 30;

In short, I need a better understanding of keyword prototype.

简而言之,我需要更好地理解关键字prototype

Thanks

谢谢

回答by MaxArt

"Prototype" is something that plays a role in objects.

“原型”是在对象中起作用的东西。

In Javascript, everything is an object. Every object has a kind, and thus inherits the prototypeof that kind.

在 Javascript 中,一切都是对象。每个对象都有一个种类,因此继承了prototype那个种类。

For example, take a simple array: var a = []. You can make operations with it, like a.push(10). Where does this pushmethod come from? From the prototype of Arrayobject, which ais.

例如,采用一个简单的数组:var a = []。您可以使用它进行操作,例如a.push(10). 这种push方法从何而来?从Array对象的原型来看,也a就是。

You can add your own methods to Arrayobjects just by defining them in the prototypeobject. For example:

Array只需在prototype对象中定义它们,您就可以将自己的方法添加到对象中。例如:

Array.prototype.sortNum = function() {this.sort(function(a, b) {return a - b});};

This way you can do something like a.sortNum()with allarrays, even the ones created before you defined the sortNummethod.

这样,你可以这样做a.sortNum()所有阵列,甚至那些你所定义的之前创建的sortNum方法。

(Note: for compatibility reasons, it's usually not recommended to extend the prototype of native objects like Arrays. But this particular example is usually a welcome addition, as well as normalizing methods like mapand forEachfor older browsers.)

(注:由于兼容性的原因,通常并不建议延长像本地对象的原型Array秒,但这个特殊的例子通常是一个值得欢迎的除了,以及标准化的方法等。mapforEach旧版本浏览器。)

(Just never everextend Object.prototype! Unless you don't care to mess up for...instatements, the inoperator and these sort of cases.)

永远不要扩展Object.prototype!除非你不想弄乱for...in语句、in运算符和这类情况。)

If you want to define your own classes, like the name MyConstructorsuggests, you'll have to define its prototypeto define the methods for all the instances of that class:

如果你想定义你自己的类,MyConstructor顾名思义,你必须定义它prototype来定义该类的所有实例的方法:

function MyConstructor(name) {this.name = name};
MyConstructor.prototype = {
    print: function() {return this.name;}
};

var mc = new MyConstructor("foo");
alert(mc.print()); // alerts "foo"

You can define more than just functions in prototypes, too:

您还可以在prototypes 中定义的不仅仅是函数:

MyConstructor.prototype.age = 30;

alert(mc.age); // alerts 30

Watch out when you do this to define "default" object values, because changing it may cause a change in allinstances of that class.

当您这样做来定义“默认”对象值时要小心,因为更改它可能会导致该类的所有实例发生更改。

But this comes handy with Object.defineProperty:

但这很方便Object.defineProperty

Object.defineProperty(MyConstructor.prototype, "wholeString", {
    get: function() {return this.name + "=" + this.age;},
    set: function(v) {this.name = v.substring(3);}
});

alert(mc.wholeString); // alerts "foo = 30"

(Unfortunately, IE<9 allows this only for DOM objects...)

(不幸的是,IE<9 只允许 DOM 对象...)

When you define MyConstructor.age = 30instead, what you're actually doing is defining a member of the functionMyConstructor, so mc.agewould be undefined. Every instance of MyConstructorinherits the methods and members defined in MyConstructor.prototype, not the ones of the function MyConstructor.

MyConstructor.age = 30相反,当您定义时,您实际上是在定义function 的一个成员MyConstructor,因此mc.age将是未定义的。的每个实例都MyConstructor继承 中定义的方法和成员MyConstructor.prototype,而不是函数的MyConstructor

There's much more to say, actually. Objects can be of a subclass of another class, thus inheriting the prototypeof the superclass, too. For example, document.bodyis an instance of HTMLBodyElement, which is a subclass of HTMLElement, which is a subclass of Elementand so on, until you get Objectas the upmost superclass. So, document.bodyinherits all the methods defined in the prototype of HTMLBodyElement, HTMLElement, Elementand Object. This is called the prototype chain.

其实还有很多话要说。对象可以是另一个类的子类,因此也可以继承prototype超类的 。例如,document.body是 的实例HTMLBodyElement,它是 的子类HTMLElement,它是 的子类Element等等,直到您Object成为最上层的超类。因此,document.body继承了所有的原型定义的方法HTMLBodyElementHTMLElementElementObject。这称为原型链。

Doing the same with custom objects is a bit tricky:

对自定义对象做同样的事情有点棘手:

function Class() {};
Class.prototype.foo = function() {alert("foo");};

function Subclass() {};
Subclass.prototype = new Class();
Subclass.prototype.bar = function() {alert("bar");};

var a = new Class(), b = new Subclass();
a.foo(); // alerts"foo"
a.bar(); // throws an error
b.foo(); // alerts "foo"
b.bar(); // alerts "bar"

a instanceof Class;    // true
a instanceof Subclass; // false
b instanceof Class;    // true
b instanceof Subclass; // true

回答by ?ime Vidas

In JavaScript, function objects have a built-in .prototypeproperty. The value of this property is an object. If the function is used as a constructor, the resulting instances inherit from that "prototype" object.

在 JavaScript 中,函数对象有一个内置.prototype属性。此属性的值是一个对象。如果该函数用作构造函数,则生成的实例将从该“原型”对象继承。

Example:

例子:

var Dog = function () {}; // the constructor function

Dog.prototype.bark = function () {}; // adding a method to Dog.prototype

var dog1 = new Dog; // creating a new instance

dog1.bark(); // the instance inherits the "bark" method from Dog.prototype

Note that the .prototypeproperty (of function objects) is not the same as the [[Prototype]]internal property. All objects contain the latter. It's an internal reference to an object's prototype. (In the above example, the dog1object's [[Prototype]]refers to Dog.prototype.) On the other hand, only function objects have a built-in .prototypeproperty (which makes sense since only function objects can be used as constructors).

请注意,.prototype(函数对象的)[[Prototype]]属性与内部属性不同。所有对象都包含后者。它是对对象原型的内部引用。(在上面的例子中,dog1对象是[[Prototype]]Dog.prototype。)另一方面,只有函数对象有一个内置.prototype属性(这是有道理的,因为只有函数对象可以用作构造函数)。

回答by Paul S.

var foo = function () {};
foo.bar = 5;
foo.prototype.foobar = 10;

var x = new foo();
x.bar; // undefined
x.foobar; // 10

Edit: Also, you can then do

编辑:另外,你可以做

foo.prototype.foobar = 20;
x.foobar; // 20