JavaScript学习笔记(三十七) 原型继承

原型继承(Prototypal Inheritance)

让我们以一种叫做原型继承(prototypal inheritance)模式开始"现代"无类的的模式("modern" classless patterns)的讨论。
在这个模式中不包含类;这里对象从其它对象继承。你可以这样想:你有一个想复用的对象,并且你想创建第二个对象并从第一个对象获取函数功能。

下面就是你如何做到这个:
// object to inherit from
var parent = {
    name: "Papa"
};
// the new object
var child = object(parent);
// testing
alert(child.name); // "Papa"
在前面这段代码块中,你有一个已经存在的对象叫做parent,通过对象字面量创建,并且你想创建另一个对象叫做child,拥有和parent相同的属性和方法。
child对象通过一个叫object()的函数创建。这个函数在JavaScript中不存在(不要和构造函数Object()弄混了),那么让我看一下你能怎样定义它。

和经典的圣杯类似,你可以使用一个空的临时构造函数F()。接着你可以设置F的prototype为parent对象。最后你返回临时构造函数的新实例:
function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}
图6-9展示了当使用原型继承模式时的原型链。这里child始终从一个空对象开始,没有自身属性但同时拥有它的parent的所有功能,得益于__proto__链接。

讨论(Discussion)

在原型继承模式,你的parent不一定非要通过对象字面量创建(虽然这可能是最常见的方式)。你可以用构造函数创建parent。
注意如果你那么做,自身属性和构造函数原型的属性都会被继承。
// parent constructor
function Person() {
    // an "own" property
    this.name = "Adam";
}
// a property added to the prototype
Person.prototype.getName = function() {
    return this.name;
};
// create a new person
var papa = new Person();
// inherit
var kid = object(papa);
// test that both the own property
// and the prototype property were inherited
kid.getName(); // "Adam"
在这种模式另外一个变种中,你可以选择只继承已经存在的构造函数的prototype对象。
记住,对象从对象继承,不管parent对象时如何被创建的。
这里是使用前面例子的一个说明,稍微修改:
// parent constructor
function Person() {
    // an "own" property
    this.name = "Adam";
}
// a property added to the prototype
Person.prototype.getName = function() {
    return this.name;
};
// inherit
var kid = object(Person.prototype);
typeof kid.getName; // "function", because it was in the prototype
typeof kid.name; // "undefined", because only the prototype was inherited

ECMAScript 5 扩展(Addition to ECMAScript 5)

在ECMAScript 5中,原型继承模式正式成为语言的一部分。这种模式实现通过Object.create()方法实现。换言之,你不需要创建你自己的类似object()的函数;它将在语言中内置:

var child = Object.create(parent);
Object.create() 接收一个额外的参数,一个对象。这个额外对象的属性将被被作为新对象的自身属性添加到新对象中,并返回新对象。
这会让你非常方便的能够实现继承,通过一个方法调用构建child对象。比如:
var child = Object.create(parent, {
    age: {
        value: 2
    } // ECMA5 descriptor
});
child.hasOwnProperty("age"); // true
你可能也发现了原型继承模式在JavaScript类库中的实现;比如YUI3,是Y.Object()方法:
YUI().use('*', function(Y) {
    var child = Y.Object(parent);
});

























猜你喜欢

转载自blog.csdn.net/qq838419230/article/details/9633343