前端面试问题之面向对象类
常见的面试问题:
- 类与实例
- 类的声明
- 生成实例
2. 类与继承
- 如何实现继承
- 继承的几种方式
其他的问题:
- 对象继承某个类,他的原型链是什么
类的声明
有两种方式
构造函数
function Animal() {
this.name = 'name';
}
ES6
class Animal () {
constructor () {
this.name = 'name';
}
}
实例化类的对象
new Animal()
类的继承
- 借助构造函数实现继承
原理: 将父级构造函数的this指向子类
function Parent () {
this.name = 'parent';
}
Parent.prototype.say = function () {}
function Child () {
// call改变执行上下文,this指向
Parent.call(this);//在子类中调用父类
this.type = 'child';
}
总结:实现部分继承,但是无法继承父类的原型方法
2. 借助原型链实现继承
原理:每个函数都有prototype属性(是个Object对象),prototype是子类构造函数的属性,Parent的实例赋值给这个属性,即new Child()._proto__ = Child.prototype = new Parent
function Parent () {
this.name = 'parent';
this.play = [1, 2, 3];
}
Parent.prototype.say = function () {}
function Child () {
this.type = 'child';
}
Child.prototype = new Parent();
console.log(Child.prototype === new Child().__proto__);
var c1 = new Child();
var c2 = new Child();
console.log(c1.play, c2.play);
c1.play.push(4);
console.log(c1.play, c2.play);
总结:继承的原型链引用同一个原型对象,多个实例更改其中一个会引起其他实例也发生更改。
3. 组合方式继承
组合构造函数继承和原型链继承方式继承
function Parent () {
this.name = 'parent';
this.play = [1, 2, 3];
}
Parent.prototype.say = function () {}
function Child () {
Parent.call(this);
this.type = 'child';
}
Child.prototype = new Parent();
console.log(new Child());
var c1 = new Child();
var c2 = new Child();
console.log(c1.play, c2.play);
c1.play.push(4);
console.log(c1.play, c2.play);
总结:父类被执行了两次,出现不必要的冗余
4. 组合继承优化方式
function Parent () {
this.name = 'parent';
this.play = [1, 2, 3];
}
Parent.prototype.say = function () {}
function Child () {
Parent.call(this);
this.type = 'child';
}
Child.prototype = Parent.prototype;
console.log(new Child());
var c1 = new Child();
var c2 = new Child();
console.log(c1.play, c2.play);
c1.play.push(4);
console.log(c1.play, c2.play);
总结:子类没有constructor,子类、父类共用一个原型类
5. 组合继承优化方式2
Object.create() 方法会使用指定的原型对象及其属性去创建一个新的对象。
function Parent () {
this.name = 'parent';
this.play = [1, 2, 3];
}
Parent.prototype.say = function () {}
function Child () {
Parent.call(this);
this.type = 'child';
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
console.log(new Child());
var c1 = new Child();
var c2 = new Child();
console.log(c1.play, c2.play);
c1.play.push(4);
console.log(c1.play, c2.play);
总结: 完美解决上述所有的问题
编辑于 2018-04-07 10:31