zoukankan      html  css  js  c++  java
  • 深入浅出:了解JavaScript的六种继承

    了解继承前我们需要了解函数的构造,方便我们理解。

     

    常见六种继承方式:
    1.原型继承call和apply;
    2.原型拷贝:循环父函数protype的key值=子函数prototype的key值;
    3.原型链继承:父函数实例继承给子函数prototype;
    4.混合继承:父函数的protype=子函数的-proto-;
    5.寄生继承:新建fn函数,其protype等于父函数protype实例,在将fn的实例等于子函数protype,加consuctor;
    6.class类继承:consuctor的super方法;

    一、call(),apply():

    一般情况下 我们只会用call和apply实现属性的继承 不会实现方法的继承;
    prototype:每一个函数都有一个prototyp属性 这个属性指向一个对象 这个对象叫做原型对象
    原型对象里面有2个属性:constructor,__proto__   
     原型链:由__proto__组成的链条叫做原型链
     

    一、它们各自的定义:

    1.apply: 调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
    2.call: 调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。 二、它们的共同之处:

    都以用来代替另一个对象调用一个方法,将一个函数的对象上下文从初始的上下文改变为由thisObj指定的新对象”。

     
    三、它们的不同之处:
    apply:最多只能有两个参数——新this对象和一个数组argArray。如果给该方法传递多个参数,则把参数都写进这个 数组里面,当然,即使只有一个参数,也要写进数组里。如果argArray不是一个有效的数组或arguments对象,那么将 导致一个TypeError。如果没有提供argArray和thisObj任何一个参数,那么Global对象将被用作thisObj,并且无法 被传递任何参数。
    call:它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表。这个方法主要用在js对象各方法 相互调用的时候,使当前this实例指针保持一致,或者在特殊情况下需要改变this指针。如果没有提供thisObj参数, 那么 Global 对象被用作thisObj。 实际上,apply和call的功能是一样的,只是传入的参数列表形式不同。*/
    /*apply()方法*/
    function.apply(thisObj[, argArray]);
    /*call()方法*/
    function.call(thisObj[, arg1[, arg2[, [, ...argN]]]]);


    举例:

    /*父类*/
    function Parent(add, net, no, teacher) {
    this.add = add;
    this.net = net;
    this.no = no;
    this.teacher = teacher
    }
    /*子类*/
    function Child(name, age, sex, id) {
    this.name = name;
    this.sex = sex;
    this.age = age;
    this.id = id;
    Parent.call(this, "山东", "www.baidu.com", "1608", "ccy"); //这个时候的Parent中的this已经被Child 所代替
    }
    var child = new Child("fangMing", "18", "男", "10086");
    console.log(child.add)
    /*如果想用apply方法,可以将注释的一句改为Parent.apply(this,["山东","www.baidu.com","1608","ccy"]), 两者的用法是一样的等效,唯一的区别就是call后面跟的是有个一个一个单独的数据,而apply需要把数据放在数组里面*/

    二、原型拷贝:

    function Person(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    }
    Person.prototype.sleep = function () { }
    Person.prototype.play = function () { }
    Person.prototype.eat = function () {
    console.log("1122")
    }
    var p1 = new Person()

    function Man(beard, larynx, name, age, sex) {

    Person.apply(this, [name, age, sex])
    this.beard = beard;
    this.larynx = larynx;
    }
    for (var key in Person.prototype) {

    Man.prototype[key] = Person.prototype[key]
    }

    Man.prototype.work = function () { }
    Man.prototype.eat = function () {
    console.log('3344')
    }

    //实例化
    var chenliang = new Man(10, "很大", "陈亮", "40", "男");
    console.log(chenliang)
    console.log([Person])
    chenliang.eat()
    p1.eat();
     
     

    三、原型链继承:

    /*
    原型链继承:实例化父函数,将其
    实例
    拷贝给子元素的prototype,这样就子函数继承了
    了父函数中的方法了。
    */
    function Person(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    }
    Person.prototype.sleep = function () { }
    Person.prototype.play = function () { }
    Person.prototype.eat = function () {
    console.log("1122")
    }
    var p1 = new Person()
    function Man(beard, larynx, name, age, sex) {
    Person.apply(this, [name, age, sex])
    this.beard = beard;
    this.larynx = larynx;
    }
    /*
    1、多了很多无用的属性---->直接使用原型链继承的时候可能把属性和方法都继承过来了
    用原型链继承的时候可能把属性放在了prototype上面
    2、少了一个constructor
    */
    Man.prototype = new Person();
    Man.prototype.work = function () { }
    //实例化
    var chenliang = new Man(10, "很大", "陈亮", "40", "男");
    console.log(chenliang)
    console.log(p1)

      四、混合继承:

    /*
    混合继承:将父函数的prototype拷贝给子函数的_proto_
    */
    //人类
    function Person(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    }
    Person.prototype.sleep = function () { }
    Person.prototype.play = function () { }
    Person.prototype.eat = function () {
    console.log("1122")
    }
    var p1 = new Person()
    //p1.__proto__:原型对象 == Person.prototype 原型对象
    function Man(beard, larynx, name, age, sex) {
    Person.apply(this, [name, age, sex])
    this.beard = beard;
    this.larynx = larynx;
    }
    /*
    1、多了很多无用的属性
    2、少了一个constructor
    */
    Man.prototype = {
    constructor: Man,
    __proto__: Person.prototype
    }
    Man.prototype.work = function () { }
    //实例化
    var chenliang = new Man(10, "很大", "陈亮", "40", "男");
    console.log(chenliang)
    console.log(p1)

    >五、寄生继承

    /*
    寄生继承:创建一个空fn函数,将父函数的prototype拷贝给fn.prototype;
    然后将子函数的prototype拷贝fn函数的实例,给子函数加一个constructor指向子函数;
    */
    //人类
    function Person(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;


    }
    Person.prototype.sleep = function () { }
    Person.prototype.play = function () { }
    Person.prototype.eat = function () {
    console.log("1122")
    }
    var p1 = new Person()
    function Man(beard, larynx, name, age, sex) {

    Person.apply(this, [name, age, sex])
    this.beard = beard;
    this.larynx = larynx;
    }
    /*
    1、多了很多无用的属性
    2、少了一个constructor
    */
    function fn() { }
    fn.prototype = Person.prototype;
    //原型链继承
    Man.prototype = new fn();
    Man.prototype.constructor = Man;
    Man.prototype.work = function () { }
    //实例化
    var chenliang = new Man(10, "很大", "陈亮", "40", "男");
    console.log(chenliang)
    console.log(p1)

    >六、Class类继承

    class Person{
    //属性
    constructor(name,age){
    this.name = name;
    this.age = age;
    }
    eat(){
    console.log('111')
    }
    show(){
    console.log('222')
    }
    }
    //ES6的继承
    class Man extends Person{
    constructor(beard,name,age){
    super(name,age)
    this.beard = beard;
    }
    work(){}
    }
    var p2 = new Man(10,"陈亮",20);
    console.log(p2)
  • 相关阅读:
    nginx通过配置防止DDoS攻击
    BZOJ 2120 数颜色(单点修改莫队)
    数论模板
    BZOJ 2002 [Hnoi2010]Bounce 弹飞绵羊(分块)
    HDU 4609 3-idiots(FFT)
    BZOJ 3527 [Zjoi2014]力(FFT)
    快速对拍
    HDU 1402 A * B Problem Plus(FFT)
    FFT
    BZOJ 5319: [Jsoi2018]军训列队(可持久化线段树)
  • 原文地址:https://www.cnblogs.com/yunshangwuyou/p/9277000.html
Copyright © 2011-2022 走看看