前言:
此时小伙伴们对“js原型原型链继承面试题”大体比较关切,我们都想要了解一些“js原型原型链继承面试题”的相关文章。那么小编也在网上搜集了一些对于“js原型原型链继承面试题””的相关文章,希望我们能喜欢,我们一起来学习一下吧!大家好,今天我来带大家深入学习一下JS面向对象三大特性——继承
一、什么是继承?
继承是面向对象中最重要的一个概念,或者说特性。
在JS语言中,继承主要是利用构造函数以及原型链实现继承效果。它可以让子类对象(实例)使用父类的所有属性以及方法,并且可以直接在子类上扩展新的属性或方法。
使用继承可以提高我们代码的复用性,从而减少我们的代码量,降低开发成本。
二、编码实现JS继承
接下来我们主要讲讲JS继承最常用的四种方法——原型链继承,借用构造函数继承,原型链和构造函数组合式继承以及ES6提供给我们的基于class类的继承。
2.1原型链继承
原理:
将子类的原型对象指向父类的实例,再将子类的原型的构造器补充完整。
技术重点:
①让子类的原型指向父类的实例:
Student.prototype=new Person();
②让子类原型的构造器指向子类本身:
Student.prototype.constructor=Student。
编码实现:
//父类
function Person() {
this.name = "Tom";
this.age = 18;
}
Person.prototype.call = function () {
console.log(`我叫${this.name}, 今年${this.age}岁`);
};
//子类
function Student() {}
//原型继承
Student.prototype = new Person();
Student.prototype.constructor = Student;
//实例化子类对象
var s = new Student();
console.log(s.name); // Tom
console.log(s.age); // 18
s.call(); // 我叫Tom, 今年18岁
优点:
子类可以继承父类所有的属性以及方法。
缺点:
①子类的所有实例共享父类的属性,对引用类型数据的修改会影响其他的实例。
②在创建子类实例时,不能向父类的构造函数传递参数。
2.2借用构造函数继承
原理:
在子类的构造函数内部使用apply或者call方法调用父类的构造函数,继承父类的属性。
技术重点:
借用父类型的构造函数,继承父类的属性:
Person.call(this,name,age)
编码实现:
//父类
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.call = function () {
console.log(`我叫${this.name}, 今年${this.age}岁`);
};
//子类
function Student(name, age) {
// 借用父类的构造函数
Person.call(this, name, age);
}
//实例化子类对象
var s = new Student("Jerry", 20);
console.log(s.name); // Jerry
console.log(s.age); // 20
s.call(); // 报错
优点:
①父类的引用属性不会被共享。
②子类的实例可以向父类传递参数。
缺点:
不能继承原型属性,父类的方法不能复用,所有的方法只能放在构造函数内部。
2.3组合式继承
原理:
利用构造函数继承和原型链的组合实现继承,解决了他们单独使用时出现的问题。
技术重点:
①借用父类型的构造函数,继承父类的属性:
Person.call(this,name,age)
②让子类的原型指向父类的实例:
Student.prototype=new Person()
③让子类原型的构造器指向子类本身:
Student.prototype.constructor=Student
编码实现:
// 父类型
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.fn = function () {};
Person.prototype.sayHello = function () {
console.log(`我叫${this.name}, 今年${this.age}岁`);
};
// 子类型
function Student(name, age, score) {
// 借用父类型的构造函数
Person.call(this, name, age);
this.score = score;
}
// 让子类的原型为父类的实例
Student.prototype = new Person();
// 让原型对象的构造器为子类型
Student.prototype.constructor = Student;
Student.prototype.sayHello = function () {
console.log(
`我叫${this.name}, 今年${this.age}岁, 考了${this.score}分`
);
};
const s = new Student("tom", 23, 95);
s.sayHello(); // 我叫tom, 今年23岁, 考了95分
s.fn();
优点:
解决了原型链继承和借用构造函数继承造成的影响。
①父类的方法可以复用。
②父类的引用数据类型属性不会被共享。
③子类创建实例时可以向父类传参。
缺点:
调用了两次父类的构造函数,一次在创建子类的原型时,另一次在子类构造函数内部。造成的性能上的浪费。
2.4class类的继承
原理:
利用ES6提供的新语法class类实现继承。
技术重点:
①子类extends(继承)父类:
class Teacher extends Person
②子类构造器中调用父类的构造函数:
super(name, age)
编码实现:
// 父类
class Person2 {
constructor(name, age) {
this.name = name;
this.age = age;
}
fn() {}
sayHello() {
console.log(`我叫${this.name}, 今年${this.age}岁`);
}
}
// 子类
class Teacher extends Person2 {
constructor(name, age, course) {
super(name, age);
this.course = course;
}
// 重写父类的方法
sayHello() {
console.log(
`我叫${this.name}, 今年${this.age}岁, 教${this.course}`
);
}
}
const t = new Teacher("jack", 34, "English");
t.sayHello(); // 我叫jack, 今年34岁, 教English
t.fn();
优点:
语法简单易懂,操作更方便。
缺点:
存在兼容性问题,不是所有的浏览器都支持。
三、结尾
好了,以上就是为大家总结的关于JS继承的编码实现原理以及方法,希望看完这篇文章后大家再也不会对继承问题感到困惑。
标签: #js原型原型链继承面试题