• 【ECMAScript5】继承


    要用 ECMAScript 实现继承机制,您可以从要继承的基类入手。所有开发者定义的类都可作为基类。出于安全原因,本地类和宿主类不能作为基类,这样可以防止公用访问编译过的浏览器级的代码,因为这些代码可以被用于恶意攻击。

    选定基类后,就可以创建它的子类了。是否使用基类完全由你决定。有时,你可能想创建一个不能直接使用的基类,它只是用于给子类提供通用的函数。在这种情况下,基类被看作抽象类。

    尽管 ECMAScript 并没有像其他语言那样严格地定义抽象类,但有时它的确会创建一些不允许使用的类。通常,我们称这种类为抽象类。

    创建的子类将继承超类的所有属性和方法,包括构造函数及方法的实现。记住,所有属性和方法都是公用的,因此子类可直接访问这些方法。子类还可添加超类中没有的新属性和方法,也可以覆盖超类的属性和方法。

    一、对象冒充

    我们先定义ClassA和ClassB

    function ClassA(sColor) {
        this.color = sColor;
        this.sayColor = function () {
            alert(this.color);
        };
    }
    
    function ClassB(sColor) {
    }

    这里的this 指向的所属的对象。这个原理是把 ClassA 作为常规函数来建立继承机制,而不是作为构造函数。如下使用构造函数 ClassB 可以实现继承机制:

    function ClassB(sColor) {
        this.newMethod = ClassA;
        this.newMethod(sColor);
        delete this.newMethod;
    }

    在这段代码中,为 ClassA 赋予了方法 newMethod(请记住,函数名只是指向它的指针)。然后调用该方法,传递给它的是 ClassB 构造函数的参数 sColor。最后一行代码删除了对 ClassA 的引用,这样以后就不能再调用它。

    所有新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法:

    function ClassB(sColor, sName) {
        this.newMethod = ClassA;
        this.newMethod(sColor);
        delete this.newMethod;
    
        this.name = sName;
        this.sayName = function () {
            alert(this.name);
        };
    }

    运行下面代码:

    var objA = new ClassA("blue");
    var objB = new ClassB("red", "John");
    objA.sayColor();    //输出 "blue"
    objB.sayColor();    //输出 "red"
    objB.sayName();        //输出 "John"

    对象冒充可以实现多重继承

    如果存在两个类 ClassX 和 ClassY,ClassZ 想继承这两个类,可以使用下面的代码:

    function ClassZ() {
        this.newMethod = ClassX;
        this.newMethod();
        delete this.newMethod;
    
        this.newMethod = ClassY;
        this.newMethod();
        delete this.newMethod;
    }

    这里存在一个弊端,如果存在两个类 ClassX 和 ClassY 具有同名的属性或方法,ClassY 具有高优先级。因为它从后面的类继承。除这点小问题之外,用对象冒充实现多重继承机制轻而易举。

    二、 call() 和 apply()

    由于这种继承方法的流行,ECMAScript 的第三版为 Function 对象加入了两个方法,即 call() 和 apply()。

    1. call() 方法

    call() 方法是与经典的对象冒充方法最相似的方法。它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身。

    function sayColor(sPrefix,sSuffix) {
        alert(sPrefix + this.color + sSuffix);
    };
    
    var obj = new Object();
    obj.color = "blue";
    
    sayColor.call(obj, "The color is ", "a very nice color indeed.");

    在这个例子中,函数 sayColor() 在对象外定义,即使它不属于任何对象,也可以引用关键字 this。对象 obj 的 color 属性等于 blue。调用 call() 方法时,第一个参数是 obj,说明应该赋予 sayColor() 函数中的 this 关键字值是 obj。第二个和第三个参数是字符串。它们与 sayColor() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息 "The color is blue, a very nice color indeed." 将被显示出来。

    要与继承机制的对象冒充方法一起使用该方法,只需将前三行的赋值、调用和删除代码替换即可:

    function ClassB(sColor, sName) {
        //this.newMethod = ClassA;
        //this.newMethod(sColor);
        //delete this.newMethod;
        ClassA.call(this, sColor);
    
        this.name = sName;
        this.sayName = function () {
            alert(this.name);
        };
    }

    ClassA 中的关键字 this 等于新创建的 ClassB 对象,因此 this 是第一个参数。第二个参数 sColor 对两个类来说都是唯一的参数。

    2. apply() 方法

    apply() 方法有两个参数,用作 this 的对象和要传递给函数的参数的数组。

    function sayColor(sPrefix,sSuffix) {
        alert(sPrefix + this.color + sSuffix);
    };
    
    var obj = new Object();
    obj.color = "blue";
    
    sayColor.apply(obj, new Array("The color is ", "a very nice color indeed."));

    该方法也用于替换前三行的赋值、调用和删除新方法的代码:

    function ClassB(sColor, sName) {
        //this.newMethod = ClassA;
        //this.newMethod(sColor);
        //delete this.newMethod;
        ClassA.apply(this, new Array(sColor));
    
        this.name = sName;
        this.sayName = function () {
            alert(this.name);
        };
    }

    如果超类中的参数顺序与子类中的参数顺序完全一致时,我们也可以把 ClassB 的整个 arguments 对象作为第二个参数传递给 apply() 方法:

    function ClassB(sColor, sName) {
        //this.newMethod = ClassA;
        //this.newMethod(sColor);
        //delete this.newMethod;
        ClassA.apply(this, arguments);
    
        this.name = sName;
        this.sayName = function () {
            alert(this.name);
        };
    }

     

  • 相关阅读:
    jQuery 简单滑动轮播图效果
    西工大:同学你好,回来挂科!
    【入门】产品经理零基础怎么入门?
    【考点】 HashMap,HashTable,CurrentHashMap,LinkedHashMap,TreeMap简述
    P图鬼才们集体上线!高校毕业照P图哪家强?
    【实战】怎样实现前端裁剪上传图片功能
    校招选产品经理岗?给你浇盆水
    战胜70%对手的校招开发岗简历是这个样子的
    两个人遇到熊,装死的和转身跑的,哪个能活下来
    第一份实习工作,我应该学到什么?
  • 原文地址:https://www.cnblogs.com/myitnews/p/12188036.html
Copyright © 2020-2023  润新知