Javascript中的原型关键字

Tin*_*tin 49 javascript html5

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

另外,以下陈述之间有什么区别?

MyConstructor.age = 30;
MyConstructor.prototype.age = 30;
Run Code Online (Sandbox Code Playgroud)

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

谢谢

Max*_*Art 65

"原型"是在物体中起作用的东西.

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

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

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

Array.prototype.sortNum = function() {this.sort(function(a, b) {return a - b});};
Run Code Online (Sandbox Code Playgroud)

这样,您可以执行a.sortNum()所有数组类似的操作,甚至是在定义sortNum方法之前创建的数组.

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

(永远不要扩展Object.prototype!除非你不关心for...in语句,in操作员和这些情况.)

如果要定义自己的类,如名称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"
Run Code Online (Sandbox Code Playgroud)

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

MyConstructor.prototype.age = 30;

alert(mc.age); // alerts 30
Run Code Online (Sandbox Code Playgroud)

请注意何时执行此操作以定义"默认"对象值,因为更改它可能会导致该类的所有实例发生更改.

但这很方便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"
Run Code Online (Sandbox Code Playgroud)

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

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

实际上还有很多话要说.对象可以是另一个类的子类,因此也继承prototype了超类的子类.例如,document.body是一个实例HTMLBodyElement,它是一个子类HTMLElement,它是一个子类,Element依此类推,直到你得到Object最高级的超类.因此,document.body继承了原型定义的所有方法HTMLBodyElement,HTMLElement,ElementObject.这被称为原型链.

对自定义对象执行相同操作有点棘手:

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
Run Code Online (Sandbox Code Playgroud)


Šim*_*das 6

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

例:

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
Run Code Online (Sandbox Code Playgroud)

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