JavaScript中的继承机制


1,对象冒充方式

  原理:构造函数使用this关键字给所有属性和方法赋值。因为构造函数只是一个函数,所有可是基类的构造函数成为子类的方法,然后调用它。子类就会收到基类的构造函数中定义的属性和方法。

    function ClassA(sColor) {
        this.color = sColor;
        this.showColor = function() {
           alert(this.color);
        };
    }
    function ClassB(sColor,sName) {
        this.newMethod = ClassA;
        this.newMethod(sColor);
        delete this.newMethod;  //删除对ClassA的引用,以后就不能在调用它。
         this.name = sName;      //所有新的属性和方法必须在删除了新方法(newMethod)的代码后定义.否则,可能会覆盖基类的相关属性和方法
         this.showName = function() {
            alert(this.name);
        };
    }
        
    var objA = new ClassA("red");
    var objB = new ClassB("blue","Nicholas");
    objA.showColor();   //outputs "red"
    objB.showColor();   //outputs "blue"
    objB.showName();    //outputs "Nicholas"

  并且对象冒充可以支持多重继承。

  例如

    function ClassZ(){
        //继承ClassX
        this.newMethod = ClassX;
        this.newMethod();
        delete this.newMethod;
 
        //继承ClassY
        this.newMethod = ClassY;
        this.newMethod();
        delete this.newMethod;
    }
但是,如果ClassX和ClassY居右相同名的属性和方法时,ClassY则具有高优先级,因为它从后面的类继承。

  2,call()方法

  基本用法:

    function showColor(sPrefix, sSuffix) {
        alert(sPrefix + this.color + sSuffix);
    };
    var obj = new Object();
    obj.color = "red";
    showColor.call(obj, "The color is ", ", a very nice color indeed."); //outputs "The color is red, 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.showName = function(){
            alert(this.name);
        };
    }

  3,apply()方法

  基本用法

    function display(sPrefix, sSuffix) {
        alert(sPrefix + this.color + sSuffix);
    }
    var obj = new Object();
    obj.color = "blue";
    display.apply(obj, new Array("111", "222"));

  同上

    function ClassB(sColor, sName) {
        ClassA.apply(this, [sColor]);
        this.name = sName;
        this.showName = function() {
            alert(this.name);
        };
    }
4,原型链

    function ClassA() {
    }
    ClassA.prototype.color = "red";
    ClassA.prototype.showColor = function(){
        alert(this.color);
    };
        
    function ClassB(){
    }
        
    ClassB.prototype = new ClassA();
    ClassB.prototype.name = "asdf"; //添加新属性和方法必须出现在对ClassB.prototype赋值完成后。
     ClassB.prototype.showName = function(){
        alert(this.name);
    };
        
    var objA = new ClassA();
    var objB = new ClassB();
    objA.color = "red";
    objB.color = "blue";
    objB.name = "adf";
    objA.showColor();
    objB.showColor();
    objB.showName();

  注意:调用ClassA的构造函数时,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。

  原型链不支持多重继承。

  5,混合方式

  就是将对象冒充与原型链方式进行组合。

    function ClassA(sColor) {
        this.color = sColor;
    }
    ClassA.prototype.showColor = function() {
        alert(this.color);
    };
    function ClassB(sColor, sName) {
        ClassA.call(this, sColor);
        this.name = sName;
    }
    ClassB.prototype = new ClassA();
    ClassB.prototype.showName = function() {
        alert(this.name);
    };
    var objA = new ClassA("red");
    var objB = new ClassB("blue", "name");
    objA.showColor();
    objB.showColor();
    objB.showName();


  附:动态原型方法不能实现继承机制。


« 
» 
快速导航

Copyright © 2016 phpStudy | 豫ICP备2021030365号-3