JavaScript继承的六种方式

JavaScript继承的六种方式

我觉得有些地方我可能理解的不是很到位,如果我下文有出现错误直接提出,谢谢~

另外可以看看这两篇文章:

https://www.cnblogs.com/humin/p/4556820.html

https://www.cnblogs.com/Grace-zyy/p/8206002.html

继承就是让子类拥有父类的资源

继承的意义

​ 减少代码冗余

​ 方便统一操作

​ 弊端

​ 耦合性比较强

继承方法

	// 父类    
	function Person() {
       this.name = 'cc';
       this.pets = ['aa', 'bb'];
    }

    Person.prototype.run = function () {
        console.log('跑');
    };

1. 原型链继承

核心:将父类的实例作为子类的原型

    // 子类        
    function Student() {
        this.num = '111';
    }
	// 让新实例的原型等于父类的实例
    Student.prototype = new Person();

    var stu = new Student();
    console.log(stu.num); // 111
    stu.run(); // 跑

	// 问题:类型问题
	console.log(stu.constructor.name); //Person  对象类型改变

优化:修复constructor指针

    // 子类        
    function Student() {
       this.num = '111';
    }

    Student.prototype = new Person();
    // 修复constructor指针即可
    Student.prototype.constructor = Student;

    var stu = new Student();
    console.log(stu.num);   // 111
    stu.run(); 				// 跑
    console.log(stu.pets);  // ["aa", "bb"]
    console.log(stu.constructor.name);  // Student

	// 问题:继承过来的实例属性, 如果是引用类型, 会被多个子类的实例共享
	var stu1 = new Student();
    stu.pets.push('dd');
    console.log(stu.pets);		// ["aa", "bb", "dd"]
    console.log(stu1.pets);		// ["aa", "bb", "dd"]

2. 借用构造函数继承

核心:在子类型构造函数的内部调用父类构造函数,通过使用call()和apply()方法可以在新创建的对象上执行构造函数。

    // 子类        
    function Student() {
       Person.call(this);
       this.num = '111';
    }
	var stu = new Student();
    console.log(stu.name);   // 111

	// 问题:没用到原型,只能继承父类的实例属性和方法,不能继承原型属性/方法
    stu.run(); 				// 报错:stu.run is not a function

3. 组合继承

核心: 将原型链和借用构造函数的技术组合在一块,从而发挥两者之长的一种继承模式。(常用)

    // 子类        
    function Student() {
       Person.call(this);
       this.num = '111';
    }

    Student.prototype = new Person();
    Student.prototype.constructor = Student;

    var stu = new Student();
    var stu1 = new Student();
    stu.pets.push('小花');
    console.log(stu.pets); 		// ["aa", "bb", "小花"]
    console.log(stu1.pets); 	// ["aa", "bb"]

	// 问题:调用了两次父类构造函数(耗内存)

4. 原型式继承

核心:借助原型,然后基于已有的对象, 创建出新对象;同时不需要创建自定义类型

用一个函数包装一个对象,然后返回这个函数的调用,这个函数就变成了一个可以随意增添属性的实例或对象。object.create()就是这个原理。

// 原型式继承
function content(obj) {
    function Temp() {}
    Temp.prototype = obj;
    return new Temp();
}
var p = new Person();
var stu1 = content(p);
console.log(stu1.name);
console.log(stu1.age);

5. 寄生式继承

核心:在原型式基础上增强这个对象。所谓增加, 就是指, 再次给这个对象增加一些属性或者方法

    // 子类        
    function Student() {
       this.num = '111';
    }

    function Temp() {}
    Temp.prototype = new Person();
    Student.prototype = new Temp();
    Temp.constructor = Student;

    var stu = new Student();
    console.log(stu);

6. 寄生式组合继承

核心:通过借用函数来继承属性,通过原型链的混成形式来继承方法。(常用)

    // 子类
	function Student(num, name, pets) {
        Person.call(this, name, pets);
        this.num = num;
    }

    function Temp() {}
    Temp.prototype = new Person();
    Student.prototype = new Temp();
    Temp.constructor = Student;

	var stu = new Student('001', '张三', ['小花']);
    var stu1 = new Student('002', '李四', ['小茂']);
    console.log(stu);
    console.log(stu1);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章