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] 实例化与原型链变更