问题描述
什么是原型
属性,为什么有必要?到目前为止,我已经了解到,这提供了公共访问对象的更多内部和私有原型
;这是正确的吗?
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?
此外,以下陈述之间的区别是什么?
Also, what's the difference between following statements?
MyConstructor.age = 30;
MyConstructor.prototype.age = 30;
简而言之,我需要更好地理解关键字 prototype
。
In short, I need a better understanding of keyword prototype
.
谢谢
推荐答案
原型是什么东西它在对象中起作用。
"Prototype" is something that plays a role in objects.
在Javascript中,一切都是对象。每个对象都有一种,因此继承了那种原型
。
In Javascript, everything is an object. Every object has a kind, and thus inherits the prototype
of that kind.
例如,取一个简单的数组: var a = []
。您可以使用它进行操作,例如 a.push(10)
。这个推送
方法来自哪里?来自 Array
对象的原型,其中 a
是。
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.
只需在 prototype
对象中定义它们,就可以将自己的方法添加到 Array
对象中。例如:
You can add your own methods to Array
objects just by defining them in the prototype
object. For example:
Array.prototype.sortNum = function() {this.sort(function(a, b) {return a - b});};
这样你可以做一些像 a.sortNum()
使用所有数组,甚至是在定义 sortNum
方法之前创建的数组。
This way you can do something like a.sortNum()
with all arrays, even the ones created before you defined the sortNum
method.
(注意:出于兼容性原因,通常不建议扩展原生对象的原型,如 Array
s。但这个特殊的例子通常是一个受欢迎的补充,如以及旧版浏览器的 map
和 forEach
等规范化方法。)
(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.)
(只是永远不会扩展 Object.prototype
!除非你不想弄乱。 ..in
语句,运算符中的和这些情况。)
(Just never ever extend Object.prototype
! Unless you don't care to mess up for...in
statements, the in
operator and these sort of cases.)
如果要定义自己的类,如名称 MyConstructor
建议,则必须将其原型
定义为为该类的所有实例定义方法:
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:
function MyConstructor(name) {this.name = name};
MyConstructor.prototype = {
print: function() {return this.name;}
};
var mc = new MyConstructor("foo");
alert(mc.print()); // alerts "foo"
您可以在原型中定义更多功能
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 all instances of that class.
但这对于 Object.defineProperty $来说非常方便c $ c>:
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"
(不幸的是,IE< 9仅允许DOM对象使用此功能。 ..)
(Unfortunately, IE<9 allows this only for DOM objects...)
当您定义 MyConstructor.age = 30
时,您实际在做的是定义一个函数的成员 MyConstructor
,因此 mc.age
将是未定义的。 MyConstructor
的每个实例都继承 MyConstructor.prototype
中定义的方法和成员,而不是函数 MyConstructor
。
When you define MyConstructor.age = 30
instead, what you're actually doing is defining a member of the function MyConstructor
, 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
.
实际上还有很多话要说。对象可以是另一个类的子类,因此也继承了超类的原型
。例如, document.body
是 HTMLBodyElement
的实例,它是 HTMLElement的子类
,这是元素
的子类,依此类推,直到你得到 Object
作为最上层的超类。所以, document.body
继承了 HTMLBodyElement
原型中定义的所有方法, HTMLElement
,元素
和对象
。这被称为原型链。
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.
对自定义对象执行相同操作有点棘手:
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
这篇关于Javascript中的原型关键字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!