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
Prototype keyword in Javascript
提问by Tintin
What is prototype
property, and why is it necessary? So far, I have learnt that this provides public access to more intrinsic, and private prototype
of 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 prototype
of 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 push
method come from? From the prototype of Array
object, which a
is.
例如,采用一个简单的数组:var a = []
。您可以使用它进行操作,例如a.push(10)
. 这种push
方法从何而来?从Array
对象的原型来看,也a
就是。
You can add your own methods to Array
objects just by defining them in the prototype
object. 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 sortNum
method.
这样,你可以这样做a.sortNum()
与所有阵列,甚至那些你所定义的之前创建的sortNum
方法。
(Note: for compatibility reasons, it's usually not recommended to extend the prototype of native objects like Array
s. But this particular example is usually a welcome addition, as well as normalizing methods like map
and forEach
for older browsers.)
(注:由于兼容性的原因,通常并不建议延长像本地对象的原型Array
秒,但这个特殊的例子通常是一个值得欢迎的除了,以及标准化的方法等。map
和forEach
旧版本浏览器。)
(Just never everextend Object.prototype
! Unless you don't care to mess up for...in
statements, the in
operator and these sort of cases.)
(永远不要扩展Object.prototype
!除非你不想弄乱for...in
语句、in
运算符和这类情况。)
If you want to define your own classes, like the name MyConstructor
suggests, you'll have to define its prototype
to 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 prototype
s, too:
您还可以在prototype
s 中定义的不仅仅是函数:
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 = 30
instead, what you're actually doing is defining a member of the functionMyConstructor
, so mc.age
would be undefined. Every instance of MyConstructor
inherits 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 prototype
of the superclass, too. For example, document.body
is an instance of HTMLBodyElement
, which is a subclass of HTMLElement
, which is a subclass of Element
and so on, until you get Object
as the upmost superclass. So, document.body
inherits all the methods defined in the prototype of HTMLBodyElement
, HTMLElement
, Element
and Object
. This is called the prototype chain.
其实还有很多话要说。对象可以是另一个类的子类,因此也可以继承prototype
超类的 。例如,document.body
是 的实例HTMLBodyElement
,它是 的子类HTMLElement
,它是 的子类Element
等等,直到您Object
成为最上层的超类。因此,document.body
继承了所有的原型定义的方法HTMLBodyElement
,HTMLElement
,Element
和Object
。这称为原型链。
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 .prototype
property. 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 .prototype
property (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 dog1
object's [[Prototype]]
refers to Dog.prototype
.) On the other hand, only function objects have a built-in .prototype
property (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