JavaScript学习笔记(三十五) 经典继承五-临时构造函数

 经典继承五-临时构造函数(Classical Pattern #5—A Temporary Constructor)

接下来这个模式解决了相同的原型的问题通过打断child原型和parent原型之间的直接关系,同时也能从原型链获益。
下面是这种模式的一个实现,你有一个空的函数F()作为一个在child和parent之间的代理,F()的prototype属性指向parent的prototype。
Child的prototype是空函数的一个实例:
function inherit(C, P) {
    var F = function () {};
    F.prototype = P.prototype;
    C.prototype = new F();
}
这种模式的表现和默认模式(经典模式#1)有些许的不同因为这里child仅仅继承prototype的属性(见图6-8)

并且这样做通常都是可行,实际上更可取,因为prototype是放复用函数的地方。在这个模式,在parent构造函数中任何添加到this的属性都不会被继承。

让我们创建一个新的child对象并观察(inspect)一下它的行为:
var kid = new Child();
如果你访问kid.name它将会是undefined。在这种情况下,name是parent的自身属性,并且在继承中,我们实际上从未调用new Parent(),所以这个属性从未被创建。
当你方法kid.say(),它在#3对象中不是有效的,那么原型链被查找。#4对象也没有这个方法,但#1对象有这个方法并且在内存中的同一个地方被所有从Parent()继承的不同构造函数和所有子构造函数创建的对象复用。

储存父类(Storing the Superclass)

构建于前面这种模式之上,你可以添加一个引用指向原始的prototype。这看起来像在其它语言中访问父类。

这个属性叫做uber,因为"super"一个保留字(reserved word)并且"superclass"可能会导致毫无戒备的程序猿误认为JavaScript有类。
这里是一个这种经典模式增强的实现:
function inherit(C, P) {
    var F = function () {};
    F.prototype = P.prototype;
    C.prototype = new F();
    C.uber = P.prototype;
}

重置构造函数引用(Resetting the Constructor Pointer)

要添加到这个近乎完美的经典继承函数的最后一件事是重置指向构造函数的引用,万一你在将来会用到。

如果你不重置指向构造函数的引用,那么所有的子对象将会报告Parent()是它们的构造函数,这个是没用的。那么使用前面的inherit()的实现,你可以观察这个行为:
// parent, child, inheritance
function Parent() {}
function Child() {}
inherit(Child, Parent);
// testing the waters
var kid = new Child();
kid.constructor.name; // "Parent"
kid.constructor === Parent; // true
这个constructor属性很少被用到但对于运行时环境判断对象非常方便。你可以重置constructor指向期望的构造函数而不影响函数的功能,因为这个属性主要是信息作用。

这个经典继承模式的最后的圣杯(Holy Grail)版本看起来就像下面一样:
function inherit(C, P) {
    var F = function () {};
    F.prototype = P.prototype;
    C.prototype = new F();
    C.uber = P.prototype;
    C.prototype.constructor = C;
}

这种模式也被称作使用代理函数(using a proxy function)或代理构造函数(proxy constructor),而不是临时构造函数(temporary constructor),因为临时构造函数被用来作为一个parent原型的代理。

圣杯模式的一个常见的优化就是防止临时(代理)构造函数在每次你需要继承的时候都被创建一次。
创建一次并仅仅改变它的prototype是足够的。你可以使用一个立即执行函数并将代理构造函数存在闭包中:
var inherit = (function () {
    var F = function () {};
    return function (C, P) {
        F.prototype = P.prototype;
        C.prototype = new F();
        C.uber = P.prototype;
        C.prototype.constructor = C;
}
}());









猜你喜欢

转载自blog.csdn.net/qq838419230/article/details/9414091
今日推荐