原型链实现继承

继承
*继承是OO(Object Oriented)语言(面向对象语言)最为人津津乐道的概念。
* 许多语言都有两种继承方式:接口继承和实现继承。
* 接口继承之继承方法签名,实现继承则继承实际的方法。
* 因为函数没有签名,在ECMAScript中无法实现接口继承。
* ECMAScript5只支持实现继承,而且实现继承只要以来原型链来实现的。

原型链
* ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法。
* 基本思想:利用原型都有一个引用类型继承另一个引用类型的属性和方法。

* 构造函数,原型,实例之间的关系:
* 每个构造函数都有一个原型(prototype),原型里有个指针(constructor)指向构造函数,
* 每个实例又有一个指针(__proto__)指向构造函数的原型对象

原型链的问题
* 包含引用类型值的原型属性会被所有实例共享,
* 这也是在构造函数中定义属性的原因所在。
* 通过原型实现继承,原型指向被继承的类的实例,就变成了被继承类的一个
* 实例,就像构造函数new一样,这样成为别的类的实例来继承别的类的属性和
* 方法

* 但是引用类型是被类的实例所共享的,问题就出现了:
*   当当前类成了别的类的实例后,再改变了它自己的引用类型,那么根据它
* 创建的新实例,新实例中原来的引用类型就会变成改变后的
    //先不实现继承,单说原型创建类
    // function Fn() {
    // }
    // Fn.prototype.color = ['red','green'];//定义在原型上的引用对象(number,string,booleans,undefined,null属于基本类型)
    //
    // let instance1 = new Fn();
    // instance1.color.push("black");
    // console.log(instance1.color);//["red", "green", "black"]
    // let instance2 = new Fn();
    // console.log(instance2.color);//["red", "green", "black"]


    function A() {
        this.name = "AName";
        this.color = ["red", "blue", "orange"];
    }

    A.prototype.nameA = function () {
        return this.name
    };

    A.prototype.toLowercase = function () {
        return "LowerCase";
    };

    function B() {
        this.name = "BName";
    }

    //继承了A
    B.prototype = new A();
    //在这之后不能使用字面量添加新的方法,会导致prototype重写,致使上一行代码无效
    // B.prototype = {
    // };
    //要谨慎的定义方法,子类型有时候需要覆盖超类型的某个方法,或者添加超类型中不存在的方法,但不管怎样,给原型添加方法的代码吗要放在替换原型之后
    //添加新方法,再继承完成后添加,否则原型链实现继承会替换整个原型,以前写的方法会被undefined
    B.prototype.toUpperCase = function () {
        return this.name.toUpperCase();
    };
    //重写超类型中方法 ,B写了一个方法,这个方法在A原型中已存在,会将A里面的这个方法覆盖,B的实例调用这个方法,就是新写的这个方法,A的实例调用这个方法还是A原型中定义的这个方法,除非A的实例也写了新方法,名字和A原型中的一样
    B.prototype.toLowercase = function () {
        return "new LowerCase";
    };

    var a = new A();
    console.log(a);
    console.log(a.toLowercase());
    var b = new B();
    console.log(b);
    console.log(b.toLowercase());
    console.log(b.toUpperCase());
    // console.log(a.color);
    // console.log(b.color);
    // b.color.push("black");
    // console.log(a.color);// ["red", "blue", "orange"]
    // console.log(b.color);// ["red", "blue", "orange", "black"]
    // var bb = new B();
    // console.log(bb.color)// ["red", "blue", "orange", "black"]
    //b发生变动后,影响到B,下一个实例也发生改动(共享),这就是原型链实现继承的问题所在
    ```
发布了68 篇原创文章 · 获赞 89 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/printf_hello/article/details/104261077