JavaScript基于原型链的继承

 

Douglas Crockford
www.crockford.com

      5年前,我写了 "Javascript中的类继承"(Chinese Italian Japanese)一文. 它展示了Javascript是一种类开放的原型语言,有足够的表达能力来模拟一个典型系统。 我的编程风格从此演变,成为任何优秀程序员都应该遵循的典范。 我已经学会了充分接受原型法则, 同时从经典模型的局限中解放了自己。

      我的征途是迂回的,因为对于它的原型特性来说,Javascript是自我矛盾的。在原型系统中,对象继承自对象。 然而,JavaScript缺乏一种能执行这种操作的方法。

      取而代之,有一种新方法,比如:

new f()

      产生了一个新对象,它继承自

f.prototype

      目的是间接地让接受过经典训练的程序员能更加熟悉这门语言, 但这么做却失败了, 因为我们只能以Java程序员的非常低级别的角度来看待JavaScript. JavaScript的构造器模式并没有吸引典型的程序员这部分人群. 这么做也掩盖了JavaScript真正的原型特性。结果,只有非常少的程序员才知道如何有效地使用这门语言。

      幸运的是,创建一个能实现真正的原型继承的操作非常简单。它是我工具包中的一个标准功能,我把它强烈推荐给你。

 function object(o) {
        function F() {}
        F.prototype = o;
        return new F();
 }

      这个object函数解决了JavaScript以构造器模式完成真正的原型继承。 它用一个老对象作为参数,返回了继承自老对象的一个空的新对象。如果我们尝试着从一个新对象中获取一个成员,而缺少一种途径,那么老对象将会提供这个成员。 对象继承自对象. 有什么比这个更面向对象?

      所以,你用创建原型对象来取代创建类,然后用object函数来创建新的实例。在JavaScript中,对象是易变的,所以我们可以声明新实例,来给对象赋予新属性和方法。 这些可以作为更新对象的原型。我们不需要用类来创建许多相似的对象。

      为了方便, 我们可以创建称为object的函数,来提供另一种自定义,比如声明带有私有函数的新对象。我有时候称之为创建者函数。如果我们有一个创建者函数,来调用另一个创建者函数,而不是调用这个object函数, 那么我们就有了一种寄生继承模式。

      我发现通过使用这些工具,加上JavaScript的lambdas(语言表达式)和quasi-literals(准字面值)对象,我可以写出那些大型、复杂、高效率的结构良好的程序。虽然经典对象模型是目前最流行的,但我认为,原型对象模型更能干,能提供更丰富的表现力。

      学习这些新的模式,也能让我成为一名更优秀的典型的程序员。来自于动态世界的见解,可以应用到静态世界。

      这里有另一种实现方式:

Object.prototype.begetObject = function () {
    function F() {}
    F.prototype = this;
    return new F();
};

newObject = oldObject.begetObject();

      object函数的问题在于,它是全局的,全局对象显然是有问题的。

      Object.prototype.begetObject的问题在于,它使得不适当的程序容易出错,当begetObject被重写时,它会产生意想不到的结果。

      所以我现在更喜欢这种方式:

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}

newObject = Object.create(oldObject);
原文地址:https://www.cnblogs.com/langtao/p/2832661.html