前端面试问题之面向对象类

前端面试问题之面向对象类

常见的面试问题:

  1. 类与实例
  • 类的声明
  • 生成实例

2. 类与继承

  • 如何实现继承
  • 继承的几种方式

其他的问题:

  • 对象继承某个类,他的原型链是什么

类的声明

有两种方式

构造函数

function Animal() {
   this.name = 'name';
}

ES6

class Animal () {
    constructor () {
       this.name = 'name';
    }
}

实例化类的对象

new Animal()

类的继承

  1. 借助构造函数实现继承

原理: 将父级构造函数的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