闭包和继承

ES6继承CLASS

  class Parent{
        constructor(n) {
            this.name = n
        }
        skill(){
            console.log(this.name + "是鉴定师")  //大老王是鉴定师
        }
    }

    class Child extends Parent{ //继承了构造函数Child的实例的原型指向parent
        constructor(n){
            super(n)//
        }
        skill(){ //不写这个方法的话,他就会继承父亲的方法,写了就执行自己的
            console.log(789)//改写不会影响parent //789
        }
    }

    var p = new Parent("大老王");
    console.log(p)//  Parent {name: "大老王"}
    p.skill();

    var c = new Child("小老王");
    console.log(c) //Child {name: "小老王"}
    c.skill();

混合继承:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>

    // 混合继承:构造函数继承+原型对象继承
    // 优点:既能继承构造函数又能继承原型,方便传参,多继承
    // 缺点:复杂
    // 常用的继承方式之一

    function Parent(n){
        this.name = n;
    }
    Parent.prototype.skill = function(){
        console.log(this.name + "是鉴定师");//parent上有原型方法; //大老王是鉴定师
    }

    function P2(){  
        this.a = 10;
    }
    P2.prototype.init = function(){
        console.log("hello")
    }

    function Child(n){ //需要Child继承构造函数中的属性,以及prototype的方法;
        Parent.call(this,n) //继承属性:在Child里面执行Parent;执行时用call将this的指向改变,同时将参数发过去。这时候就将构造函数中的Name继承过来了。
        P2.call(this) //同理,注意这里没有参数,所有this后不需要添加一个参数。
    }
    for(var i in Parent.prototype){ //使用原型对象形式做一个深拷贝,拷贝Parent的原型对象
        Child.prototype[i] = Parent.prototype[i] //使 Child.prototype的值与Parent.prototype的值一样;
    }
    for(var i in P2.prototype){
        Child.prototype[i] = P2.prototype[i]
    }

    Child.prototype.skill = function(){ //对Child中的prototype的方法进行修改,不会影响Parent中的原型方法
        console.log(123)
    }
    
    var p = new Parent("大老王");
    console.log(p) //Parent(构造函数)
    p.skill(); //大老王是鉴定师

    var c = new Child("小老王");
    console.log(c)//Child(构造函数)
    c.skill();//123
    c.init();//hello

</script>
</html>

原型继承:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>

    // 原型对象继承:继承原型
    // 优点:简单,方便,可以继承原型身上的方式和属性
    // 缺单:只能继承原型,不方便传参


    function Parent(n){
        this.name = n;
    }
    Parent.prototype.skill = function(){
        console.log(this.name + "是鉴定师");
    }

    function Child(n){}

    // 注意:对象的深浅拷贝
    // Child.prototype = Parent.prototype;
    for(var i in Parent.prototype){
        Child.prototype[i] = Parent.prototype[i];
    }

//     Child.prototype.skill = function(){
//         console.log("采矿");    //不会影响Parent中的方法。

    var p = new Parent("大老王");
    console.log(p)
    p.skill();

    var c = new Child("小老王");
    console.log(c)
    c.skill();

</script>
</html>

原型链继承:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    
</body>
<script>

    // 原型链继承:通过给Child设置原型为Parent的实例的方式,给Child添加了一层原型链的方式
    // 优点:既能继承原型,又能继承构造函数
    // 缺点:复杂,不方便传参

    function Parent(n){
        this.name = n;
    }
    Parent.prototype.skill = function(){
        console.log(this.name + "是鉴定师");
    }

    function Child(){}
    Child.prototype = new Parent("小老王");

//    Child.prototype.skill = function(){
//        console.log(12312312)  //不会影响所继承的父级
//    }

    var p = new Parent("大老王");
    console.log(p) //Parent(构造函数)
    p.skill();  //大老王是鉴定师
    // p是实例(对象),有__proto__属性,指向Parent.prototype

    var c = new Child();
    console.log(c);  //Child(构造函数)
    c.skill();     //小老王是鉴定师 //自己可设置skill的方法,那样就不会继承了父级的方法
    // c是实例(对象),有__proto__属性,指向Child.prototype,是Parent的实例(对象),有__proto__属性,指向Parent.prototype

</script>
</html>

实例与构造函数的关系

<script>
function Parent(n){
        this.name = n;
    }
    Parent.prototype.skill = function(){
        console.log(this.name + "是鉴定师");
    }

    function P2(){
        this.a = 10;
    }
    P2.prototype.init = function(){
        console.log("hello")
    }

    function Child(n){
        Parent.call(this,n)
        P2.call(this)
    }
    Child.prototype = new Parent();

   

    var p = new Parent("大老王");
    var c = new Child("小老王");
    console.log(c) //可以看到c的原型指向parent的实例Parent;
    //Parent的实例指向了自己的构造函数。
    var a = new Array();

    //左边是父 括号中是子元素,左边是个原型对象,右边是个实例
     console.log(Parent.prototype.isPrototypeOf(c))  //t Child的实例是否指向Parent的原型。或者说是Parent的构造函数是否被c指向。
     console.log(Parent.prototype.isPrototypeOf(a))  //f
     console.log(Array.prototype.isPrototypeOf(a))   //t 数组属于Array的这个原型,所以为true
     console.log(Object.prototype.isPrototypeOf(a))  //t
     console.log(Object.prototype.isPrototypeOf(c))  //t
     console.log(Object.prototype.isPrototypeOf(p))  //t
    //所有的实例,对象都属于object,所以那object测都是true;




  //左边是子右边是父。左边是实例,右边不是对象是构造函数本身
    console.log(c instanceof Child);    //t检测c是否是从构造函数child中来的;
    console.log(c instanceof Parent);   //t检测c是否是从构造函数parent中来的;因为他是继承来的;
    console.log(c instanceof Array);    //f
    console.log(c instanceof Object);   //t
    console.log(p instanceof Child);    //f
</script>
原文地址:https://www.cnblogs.com/hy96/p/11536915.html