JS中简单的几种继承方法(不含ES6)
1、继承介绍
-
生活:子承父业
-
编程:类与类之间的关系。子类继承父类中的成员
-
不使用继承,类与类之间可能有重复的属性和方法:
-
学生类:姓名、年龄、性别、学号、打招呼、跑
-
医生类:姓名、年龄、性别、钱、打招呼、跑
-
老师类:姓名、年龄、性别、工号、打招呼、跑
-
......
-
-
使用继承,把不同类之间相同的属性和方法重新定义为一个类的:
-
人类[父类]:姓名、年龄、性别、打招呼、跑
-
学生类[子类]→人类[父类]
-
医生类[子类]→人类[父类]
-
老师类[子类]→人类[父类]
-
......
-
-
2、原型继承
-
优缺点:
-
优点:完美继承了方法
-
缺点:无法完美继承属性
-
-
如何实现原型继承:
-
①先更改子类的原型prototype指向父类的一个实例对象。
-
子类.prototype = new 父类();
-
-
②再给子类的原型(即new 父类())设置一个constructor指向该子类
-
子类.prototype.constructor = 子类;
-
-
-
图解:
-
代码:
1 // 人类 → 父类 2 function Person() { 3 this.name = '名字'; 4 this.age = 10; 5 this.gender = '男'; 6 } 7 Person.prototype.sayHi = function () { console.log('你好'); }; 8 Person.prototype.eat = function () { console.log('我会吃。。。'); }; 9 Person.prototype.play = function () { console.log('我会玩'); }; 10 11 12 // 学生类 → 子类 13 function Student() { 14 this.stuId = 1000; 15 } 16 // 子类的原型prototyp指向父类的一个实例对象 17 Student.prototype = new Person(); 18 19 // 添加一个constructor成员 20 Student.prototype.constructor = Student; 21 22 // 如何实现原型继承: 23 // 给子类的原型prototype重新赋值为父类的一个实例对象。 24 // 利用了原型链上属性或方法的查找规则。 25 26 27 // 创建一个学生对象 28 var stu1 = new Student(); 29 console.log(stu1.constructor)
3、借用继承
- 本质就是改变父类构造函数中this指向子类(这里使用call方法),子类调用父类属性
-
优缺点:
-
优点:完美继承了属性
-
缺点:无法继承方法。
-
3.1 call方法
-
语法: 函数名.call(调用者,函数实参,函数的实参...);
-
作用:该函数会立即执行,函数体内的this在被call时,this指向调用者。
-
代码:
1 function Person(userName,age) { 2 console.log(this===obj); 3 this.userName = userName; 4 this.age = age; 5 } 6 // 需求:通过一种方式调用执行Person函数,并且函数内部this代表obj 7 var obj = {}; // new Object() 8 Person.call(obj,'张三',10); //==>Person中的this指向obj
3.2 使用call实现借用继承
-
如何实现:
-
在子类中,通过call调用父类,并更改父类中this的指向子类对象。
-
-
图解:
-
代码:
1 // 人类 → 父类 2 function Person(name,age,gender) { 3 this.name = name; 4 this.age = age; 5 this.gender = gender; 6 } 7 Person.prototype.sayHi = function () { console.log('你好'); }; 8 Person.prototype.eat = function () { console.log('我会吃。。。'); }; 9 Person.prototype.play = function () { console.log('我会玩'); }; 10 11 12 // 学生类 → 子类 13 function Student(name,age,gender,stuId) { 14 // this关键字代表谁,代表的是一个学生对象,当前创建的对象 stu1 ,stu2 15 // var obj = this; 16 //【借用继承】 17 // Person.call(obj,name,age,gender); 18 Person.call(this,name,age,gender); 19 this.stuId = stuId; 20 } 21 22 23 // 创建第一个学生对象 24 var stu1 = new Student('张三',10,'男',10086); 25 // 创建第二个学生对象 26 var stu2 = new Student('李四',11,'女',10010);
3.3 利用apply实现继承(同上)
- 代码:
1 function person(name,age) { 2 this.name = name; 3 this.age = age; 4 } 5 function man(name,age){ 6 person.apply(this,[name,age]); //这里就是伪造成 person 的一个事例 7 } 8 var Man = new man('wozien',12); 9 console.log(Man.name); 10 console.log(Man.age);
4、组合继承
-
如何实现:
-
原型继承和借用继承同时使用。
-
-
代码:
1 // 人类 → 父类 2 function Person(name,age,gender) { 3 this.name = name; 4 this.age = age; 5 this.gender = gender; 6 } 7 Person.prototype.sayHi = function () { console.log('你好'); }; 8 Person.prototype.eat = function () { console.log('我会吃。。。'); }; 9 Person.prototype.play = function () { console.log('我会玩'); }; 10 11 12 // 学生类 → 子类 13 function Student(name,age,gender,stuId) { 14 //【借用继承】 15 Person.call(this,name,age,gender); 16 this.stuId = stuId; 17 } 18 19 // 【原型继承】 20 Student.prototype = new Person(); 21 Student.prototype.constructor = Student; 22 23 24 // 创建第一个学生对象 25 var stu1 = new Student('张三',10,'男',10086); 26 // 创建第二个学生对象 27 var stu2 = new Student('李四',11,'女',10010);