zoukankan      html  css  js  c++  java
  • JavaScript 的几种继承方式

    JavaScript 的几种继承方式

    • 原型链继承
    • 构造函数继承
    • 组合继承 (伪经典继承)
    • 原型式继承
    • 寄生式继承
    • 寄生组合式继承
    • ES6 extend 继承

    1, 原型链继承

    原理是将父对象的属性和方法通过prototype进行引用

    function people() {
        this.flag = true;
        this.func = function() {
            console.log("this is people func");
        }
    }
    function boy() {
        this.sex = "boy";
    }
    boy.prototype = new people();
    var peo1 = new boy();
    console.log( peo1.flag );     // true
    console.log( peo1.func() );   // this is people func
    console.log( peo1.sex );      // boy
    

    缺点:

    • 实例对象的属性被共享
    • 无法向父对象的方法传递参数

    2, 构造函数继承

    构造函数继承主要在继承对象中使用 call()、apply() 完成。

    function people(name) {
        this.name = name || "xiaoming";
    }
    
    // 对people进行继承
    function boy() {
        people.call(this, "wangming");
        this.age = 18;
    }
    var peo1 = new boy();
    console.log( peo1.name ); //wangming
    console.log( peo1.age ); //18
    

    缺点:

    • 函数无法复用
    • 父对象的方法对子类不可见

    3, 组合继承 (伪经典继承)

    结合原型链和构造函数继承。思路是利用原型链继承原型上的属性和方法,构造函数继承实例的属性,也就是父对象自己的属性。

    function people(name) {
        this.name = name || "xiaoming";
    }
    people.prototype.sayName = function() {
        alert(this.name);
    }
    
    //构造函数继承属性
    function boy(name, age) {
        people.call(this, name);
        
        this.age = age || 18;
    }
    //原型链继承方法
    boy.prototype = new people();
    boy.prototype.sayAge = function() {
        alert(this.age);
    }
    
    var peo1 = new boy("zhangsan", 22);
    peo1.sayName();  // zhangsan
    peo1.sayAge();   // 22
    

    因为结合了原型链和构造函数继承的优点,成为了最常用的继承模式。但也有缺点,就是调用了两次父对象的构造函数。(使用call时一次,使用new又是一次)

    4,原型式继承

    这种继承模式的思路是创建一个基本对象,里面包含通用的属性、函数。通过特定函数创建实例。

        function object(o) {
            function F() {}
            F.prototype = o;
            return new F();
        }
    

    利用该函数创建的实例对象其实是原来基本对象的副本。ES5中新增了Object.create()对其进行规范。兼容IE9+。

    var person = {
        name: "Neo",
        sayName: function() {
            console.log(this.name);
        }
    }
    var obj = Object.create(person);
    obj.name = "test";
    obj.sayName();    // test
    person.sayName(); // Neo
    

    5,寄生式继承

    寄生式与原型式相关。用一个函数封装继承过程,类似于工厂模式。

    function createAnother( obj ) {
        var clone = Object.create(obj);
        clone.sayName = function() {
            alert(this.name);
        }
        return clone;
    }
    var people = {
        name: "test"
    }
    var boy = createAnother(people);
    boy.sayName(); // test
    

    6,寄生组合式继承

    寄生式继承与组合式继承,实现一种最理想的继承模式。

    function inheritPrototype( subItem, superItem ) {
        var clone = Object.create(superItem.prototype);
        clone.constructor = subItem;
        subItem.prototype = clone;
    }
    function superItem(name) {
        this.name = name;
    }
    superItem.prototype.sayName = function() {
        alert(this.name);
    }
    
    function subItem(name, age) {
        superItem.call(this, name);
        this.age = age || 18;
    }
    inheritPrototype(subItem, superItem);
    
    var obj = new subItem("leo");
    obj.sayName();    //leo
    

    7, ES6 extend 继承

    利用ES6提供的类继承关键字extends实现。

    class People {
        constructor(){
            this.name = "leo";
        }
        sayName(){
            alert(this.name);
        }
    }
    class Boy extends People{
        constructor(props){
            super(props);
            this.name = "li"
        }
    }
    var peo1 = new People();
    var peo2 = new Boy();
    
    peo1.sayName(); // leo
    peo2.sayName(); // li
    

    以上就是我所总结的7中继承方式

  • 相关阅读:
    angular4升级angular5问题记录之this.location.back()
    angular4升级angular5问题记录之No NgModule metadata found for 'AppModule'
    Angular4图片上传预览路径不安全问题
    Angular4.0引入laydate.js日期插件方法
    Angular4.0用命令行创建组件服务出错
    IE10以下的img标签问题
    关于for循环删除数组内容出现的问题
    关于onmouseover和onmouseout的bug
    纯lua实现Base64加密与解密
    SciTE如何修改背景色
  • 原文地址:https://www.cnblogs.com/miku561/p/10487017.html
Copyright © 2011-2022 走看看