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)
  • 相关阅读:
    UVALive 7141 BombX
    CodeForces 722D Generating Sets
    CodeForces 722C Destroying Array
    CodeForces 721D Maxim and Array
    CodeForces 721C Journey
    CodeForces 415D Mashmokh and ACM
    CodeForces 718C Sasha and Array
    CodeForces 635C XOR Equation
    CodeForces 631D Messenger
    田忌赛马问题
  • 原文地址:https://www.cnblogs.com/yunshangwuyou/p/9277000.html
Copyright © 2011-2022 走看看