前端必刷手写题系列 [20]

285 阅读3分钟

这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战

这个系列也没啥花头,就是来整平时面试的一些手写函数,考这些简单实现的好处是能看出基本编码水平,且占用时间不长,更全面地看出你的代码实力如何。一般不会出有很多边界条件的问题,那样面试时间不够用,考察不全面。

平时被考到的 api 如果不知道或不清楚,直接问面试官就行, api 怎么用这些 Google 下谁都能马上了解的知识也看不出水平。关键是在实现过程,和你的编码状态习惯思路清晰程度等。

注意是简单实现,不是完整实现,重要的是概念清晰实现思路清晰,建议先解释清楚概念 => 写用例 => 写伪代码 => 再实现具体功能,再优化,一步步来。

29. class/extends

问题是什么

继承是 OOP (面向对象编程)(Object-oriented programming) 的核心概念,本文是介绍js 中各种继承的简单手写。

上两篇篇我们主要讲了

  • 原型链继承
  • 构造函数继承
  • 组合继承
  • 寄生式继承
  • 寄生组合式继承

如果没了解过,请先看看

那么现在我们看看 class/extends

class

看这个方法前,我们先回顾下用一般函数实现Parent的方法:

function Parent (name, actions) {
    this.name = name;
    this.actions = actions;
}

Parent.prototype.play = function () {
  console.log(`${this.name} is playing`)
}

而用 class 语法的话,长这样

// class 本质还是函数
class Parent {
    constructor(name, actions) {
        this.name = name;
        this.actions = actions;
    }

    play() {
        console.log(`${this.name} is playing`)
    }
}

tips: 注意函数中间是没有 ,

那么下面新建子类 Child, 用 extends

extends

// extends 继承更方便
class Child extends Parent {
    constructor(name, actions, age) {
        // super 调用父类的构造方法
        super(name, actions); 
        this.age = age;
    }

    introduce() {
        console.log(`I'm ${this.name}, I'm ${this.age}`)
    }
}

这样我们不但获得了父类 Parent 的属性方法而且还自己定义了新的属性和方法。接下来用用看

let child1 = new Child('keal', ['alive, play'], 25)

console.log(child1.name);      // keal
console.log(child1.actions);   // ['alive, play']
console.log(child1.age);       // 25
child1.introduce()             // I'm keal, I'm 25

// 下面是继承父类的属性方法
console.log(child1.language);  // zh
child1.play()                  // keal is playing

// 我们看看之前的那些个问题情况, 比如方法内存占用过多啊,引用类型的属性没有被所有实例共享等

let child2 = new Child('more', ['code, eat'], 28)

// 引用类型属性互不影响
child1.actions.push('coding');
console.log(child1.actions) // [ 'alive, play', 'coding' ]
console.log(child2.actions) // [ 'code, eat' ]

// 无论自定义,还是继承的方法,都是一份引用
console.log(child1.play === child2.play) // true
console.log(child1.introduce === child2.introduce) // true

另外我们 extends 语法的强大之处就在于,在 extends 后允许任意表达式,当我们需要根据许多条件使用函数生成类,并继承它们时会很有用, 举个例子

function choosePat(type) {
  return class {
    constructor (name) {
      this.name = name
      this.action = type === 'cat' ? 'sleep' : 'run'
    }

    sound() {
      type === 'cat' ? console.log('miao ~~') : console.log('rua ~~')
      
    }
  }
}

class MyCat extends choosePat('cat') {
  constructor (name) {
    super(name)
    this.master = 'k'
  }
}

let pat = new MyCat('little ball')

console.log(pat.master)  // k
console.log(pat.name)  // little ball
pat.sound()   // miao ~~

你当然可以用更多方式去动态复用类。以后讲设计模式可以回到这个地方看看。

另外向大家着重推荐下另一个系列的文章,非常深入浅出,对前端进阶的同学非常有作用,墙裂推荐!!!核心概念和算法拆解系列 记得点赞哈

今天就到这儿,想跟我一起刷题的小伙伴可以加我微信哦 点击此处交个朋友 Or 搜索我的微信号infinity_9368,可以聊天说地 加我暗号 "天王盖地虎" 下一句的英文,验证消息请发给我 presious tower shock the rever monster,我看到就通过,加了之后我会尽我所能帮你,但是注意提问方式,建议先看这篇文章:提问的智慧

参考