• es5继承和es6类和继承


      es6新增关键字class,代表类,其实相当于代替了es5的构造函数

        通过构造函数可以创建一个对象实例,那么通过class也可以创建一个对象实列

    /* es5 创建一个person 构造函数 */
    function person (name,age) {
        this.name = name
        this.age = age
    }
    /* 定义原型链上的方法sayholle */
    /* 为什么要将方法定义在原型上,定义在原型上的方法,所有的实例对象都共享 
     不会出现没实列一个对象都重新创建一个这个方法 */
    person.prototype.sayholle = function () {
        console.log(this.name+' holle'+ this.age)
    }
    
    let person1 = new person('czcz','23')
    person1.sayholle()  //  czcz holle23
    
    /* es6 使用class创建一个对象 */
    class personclass {
        /* 实列对象时默认调用的方法 */
        constructor (name,age) {
            this.name = name
            this.age = age
        }
        /* 定义一个方法,相对构造上述原型链上的方法 */
    
        sayholle () {
            console.log(this.name+' holle'+ this.age)
        }
    }
    let person2 = new personclass('czcz','26')
    person2.sayholle()  //  czcz holle23

      es5中继承的方式

        1原型链继承

    /* es5原型链继承 */
    function person (name,age) {
        this.name = name
        this.age = age
    }
    person.prototype.sayholle = function () {
        console.log(this.name+' holle'+ this.age)
    }
    
    function child (sex) {
        this.sex = sex;
    }
    child.prototype = new person();
    child.prototype.hh = 'ddd'
    let p = new child('man')
    console.log(p) // 
    console.log(new person());
    let p2 = new child('man')
    p2.__proto__.age = '36'
    /* 给p2原型上的age赋值,则导致p上的age也改变,父类构造函数上的属性被所有子类共享 */
    console.log(p) // 36
    /* 缺点,child 新增的属性只能在new person 以后,创建实列时无法向
        父类的构造函数传送参数,因为直接是指定了原型,所有也不能实现多继承
        父类构造函数上的属性被所有子类共享
    */

        2.构造函数继承

    /* es5构造函数继承 */
    function person (name,age) {
        this.name = name
        this.age = age
    }
    person.prototype.sayholle = function () {
        console.log(this.name+' holle'+ this.age)
    }
    function child (sex,name,age) {
        this.sex = sex
        person.call(this,name,age)
    }
    
    let p = new child('man','czklove','13')
    console.log(p);
    /* 
        可以是先多继承,只要执行多个call
        创建实列时能像父类构造函数船体参数
        不会出现父类属性,所有子类构造函数共享
        缺点,
        不能继承父类原型链上的方法,如上面不能掉用sayholle方法
        子类构造函数的实列,原型链上并不存在父类构造函数,
        因为不能继承父类原型链上的函数,所有要继承函数只能定义在父类构造函数上,
        不能达到函数复用
     */

        3.组合继承,融合了上面两种方式

    /* es5组合继承 */
    function person (name,age) {
        this.name = name
        this.age = age
    }
    person.prototype.sayholle = function () {
        console.log(this.name+' holle'+ this.age)
    }
    function child (sex,name,age) {
        this.sex = sex
        person.call(this,name,age)
    }
    child.prototype = new person();
    /* 重新设置一下constructor 不设置也没有影响,严谨的角度上来说还是设置一下*/
    /* 不设置的话,__proto__ 上时没有 constructor */
    /* 正常来讲constructor是指向自身的 */
    child.prototype.constructor = child;
    let p = new child('man','czklove','13')
    let p1 = new child('man','czklove1','16')
    p.sayholle(); // czklove holle13
    console.log(p);
    1. child {sex: "man", name: "czklove", age: "13"}
      1. age: "13"
      2. name: "czklove"
      3. sex: "man"
      4. __proto__: person
        1. age: undefined
        2. constructor: ƒ child(sex,name,age)
        3. name: undefined
        4. __proto__: Object
    
    
        /*
        组合继承,既能达到对父类属性的继承,也能继承父类原型上的方法
        父类属性继承也不会在所有子类的实列上共享
        唯一缺点,子类原型上有父类构造函数的属性,也就是多了一份属性
        */
    
    console.log(p.__proto__ === child.prototype) //true

        4.优化版的组合继承(寄生组合继承)

    /* es5寄生组合继承 */
    function person (name,age) {
        this.name = name
        this.age = age
    }
    person.prototype.sayholle = function () {
        console.log(this.name+' holle'+ this.age)
    }
    function child (sex,name,age) {
        this.sex = sex
        person.call(this,name,age)
    }
    child.prototype = Object.create(person.prototype);
    child.prototype.constructor = child
    let p = new child('man','czklove','13')
    p.sayholle(); // czklove holle13
    console.log(p);
    /*  child {sex: "man", name: "czklove", age: "13"}
        age: "13"
        name: "czklove"
        sex: "man"
        __proto__: person
        constructor: ƒ child(sex,name,age)
        __proto__:
        sayholle: ƒ ()
        constructor: ƒ person(name,age)
        __proto__: Object */

      es6 class

        1.1class 内部都是严格模式

        1.2class 不存在变量提升

        1.3 class 的 name属性

        1.4 实现symbol.iterator 接口,可以使用for of 遍历属性

        1.5this 指向实例内部

      关于class的基本介绍,去阮一峰老师的es6入门看就行 http://es6.ruanyifeng.com/#docs/class

      es6 class的继承

    /* esl class */
    class person {
        constructor (name,age) {
            this.name = name
            this.age = age
        }
        syaholle () {
            console.log(this.name+ ' holle '+this.age)
        }
    }
    
    class child extends person {
        constructor (name,age,sex) {
            /*  执行父类的构造函数 
                子类必须在构造函数中掉用super
                */
            super(name,age)
            /* 使用this一定要在super 之后 */
            this.sex = sex
        }
    }
    
    let p = new child('czklove','23','man')
    console.log(p)
    /*  child {name: "czklove", age: "23", sex: "man"}
        age: "23"
        name: "czklove"
        sex: "man"
        __proto__: person
        constructor: class child
        __proto__:
        constructor: class person
        syaholle: ƒ syaholle()
        __proto__: Object */
    /* esl class */
    class person {
        constructor (name,age) {
            this.name = name
            this.age = age
        }
        syaholle () {
            console.log(this.name+ ' holle '+this.age)
        }
    }
    
    class child extends person {
        constructor (name,age,sex) {
            /*  执行父类的构造函数 
                子类必须在构造函数中掉用super
                */
            super(name,age)
            /* 使用this一定要在super 之后 */
            this.sex = sex
        }
    }
    
    let p = new child('czklove','23','man')
    console.log(p)
    /*  child {name: "czklove", age: "23", sex: "man"}
        age: "23"
        name: "czklove"
        sex: "man"
        __proto__: person
        constructor: class child
        __proto__:
        constructor: class person
        syaholle: ƒ syaholle()
        __proto__: Object */

      es6 class 还涉及到很多东西,

          1.静态方法

          2.this指向

          3.super 关键字的具体使用

          4.类的prototype属性,构造函数的__proto__

          5.原生构造函数的继承,如Array的继承,Boolean,Number,String Date...

      基础简单的这里就不说了

      我们再看以下原生构造函数的继承

        es5中是不允许原生构造函数的继承的

      

    /*  es5为什么不能对原生构造函数的继承
        通过es5继承我们知道,继承父类构造属性是通过person.call(this,argument)
        (es6)
        是因为子类无法获得原生构造函数的内部属性,
        通过Array.apply()或者分配给原型对象都不行。
        原生构造函数会忽略apply方法传入的this,也就是说,
        原生构造函数的this无法绑定,导致拿不到内部属性
    */
    /* es6 使用class继承原生 */
    
    class myarray extends Array {
        constructor(...argus) {
            super(...argus)
        }
    }
    
    let arrays = new myarray();
    arrays[0] = 'czklove';
    console.log(arrays);
    arrays.length = 0
    console.log(arrays);
    
    /*  输出
        myarray ["czklove"]
        myarray [] */

      注,es6对object构造函数的继承,不能传参,传参数无效

    class newobjext extends Object {
        constructor() {
            super(...arguments)
        }
    }
    let o = new newobjext({name: 'czklove'})
    console.log(o.name); // undefined

      总结,

        es5的继承

        1.1原型链继承

        1.2 构造函数继承

        1.3组合继承

        1.4寄生组合继承

        es6 的 extends  继承

        super 关键字的使用,新增的静态字段使用,支持对原生构造函数的继承,对object继承的差异

  • 相关阅读:
    终端操作各插件安装配置
    浅谈CSRF攻击方式
    教你突破基于HTTP_REFERER的防盗链的方法
    HTTP Referer简介
    如何利用百度蜘蛛referer找到报错页面入口?
    Flex 布局教程:语法
    HTTP 状态码
    RESTful API 设计最佳实践
    Javascript原型和原型链
    JS判断是什么设备是什么浏览器-主要用移动页面开发
  • 原文地址:https://www.cnblogs.com/czkolve/p/10849226.html
Copyright © 2020-2023  润新知