extends关键字

2020/05/24 Javascript 共 1533 字,约 5 分钟

extends关键字

extends的等价实现

class Foo {}
class Bar extends Foo {}

// 等价于
function Foo() {}
function Bar() {}
// Bar extends Foo
Bar.prototype = Objcet.create(Foo.prototype)

等价实现的方式需要额外关注constructor,参考实例化与原型链变更

extends意义

拓展原生类

一般地,如果不使用class的方式,我们可以通过原型链拓展的方式进行原生类拓展,实现如下,需要额外注意不要污染原生类的原型链:

let arrProto = Object.create(Array.prototype)
arrProto.first = function () {
  return this[0]
}
arrProto.last = function () {
  return this[this.length - 1]
}
let arr = [0, 1, 2, 3]
console.log('it should be [0]:', arrProto.first.call(arr));
console.log('it should be [3]:', arrProto.last.call(arr));
console.log('it should be [4]:', arr.length)
arr.push(4)
console.log('it should be [4]:', arrProto.last.call(arr));
console.log('it should be [5]:', arr.length)
arr[5] = 6
console.log('it should be [6]:', arrProto.last.call(arr));
console.log('it should be [6]:', arr.length)

通过上面的方式,实现比较繁琐:

  • 我们首先需要复制原型出来,目的是防止原型链污染
  • 接着我们需要通过改变this指向的方式,通过自建的原型链调用目标arr

通过class拓展原生类的方式会更清晰,更好理解一点:

class MyArr extends Array {
  first() {
    return this[0]
  }
  last() {
    return this[this.length - 1]
  }
}
// 需要注意,这里 MyArr 即 []
let arr = new MyArr(0, 1, 2, 3)
console.log('it should be [0]:', arr.first())
console.log('it should be [3]:', arr.last())
arr.push(4)
console.log('it should be [4]:', arr.last())

堆栈错误捕获

真正的Error对象创建时,会自动捕获特殊的stack信息,包括生成错误时的行号和文件名等信息

传统方式抛出错误:

function test() {
  throw new Error(123)
}
/* 
  main.js:2 Uncaught Error: 123
    at test (main.js:2:9)
    at main.js:4:1
 */
test()

通过拓展错误子类的方式,更方便的定义自定义错误类型:

class NetWorkErr extends Error {
  constructor(reason) {
    super(reason)
    this.message = `[newWorkErr]: ${reason}`
  }
}
/* 
  main.js:20 Uncaught Error: [newWorkErr]: offline
    at main.js:20:18
 */
let netWorkErr = new NetWorkErr('offline')
throw netWorkErr

[1] 实例化与原型链变更

Search

    Table of Contents