劈头
近来在运用 Symbol 来做为唯一值,发明 Symbol 没法举行 new 操纵,只能看成函数运用,只需举行了new 就会发作范例毛病
new Symbol()
// error
Uncaught TypeError: Symbol is not a constructor
at new Symbol (<anonymous>)
at <anonymous>:1:1
在不斟酌底层完成的情况下,在代码层面是不是能够完成一个函数只能够举行挪用而不能够举行 new 操纵呢?思索以后以下写出:
function disConstructor() {
if (this !== window) {
throw new TypeError(' disConstructor is not a constructor')
}
console.log('gogo go')
}
// 测试效果以下
disConstructor() // gogo go
new disConstructor()
// error
Uncaught TypeError: disConstructor is not a constructor
at new disConstructor (<anonymous>:3:15)
at <anonymous>:1:1
假如运用 nodejs,window 能够切换为 global, 代码运转效果稳定,由于关于个人而言没有实用场景。因而就没有继续研讨下去,然则近来在重新翻阅 es6 时刻发明 new.target这个属性。
new.target 属性
引见(援用 mdn 文档)
new.target属性许可你检测函数或组织要领是不是是经由历程new运算符被挪用的。
在经由历程new运算符被初始化的函数或组织要领中,new.target返回一个指向组织要领或函数的援用。在一般的函数挪用中,new.target 的值是undefined。
如许的话 我们的代码就能够如许改成
function disConstructor() {
// 一般的函数挪用中,new.target 的值是undefined。
if (new.target) {
throw new TypeError(' disConstructor is not a constructor')
}
console.log('gogo go')
}
获得与上述代码一样的答案。
深切
岂非 es6 专程增添的功用仅仅只能用于检查一下我们的函数挪用体式格局吗?
在查阅的历程种种发明了大多数都计划都是用 new.target 写出只能被继续的类。类似于完成java的笼统类。
class Animal {
constructor(name, age) {
if (new.target === Animal) {
throw new Error('Animal class can`t instantiate');
}
this.name = name
this.age = age
}
// 其他代码
...
}
class Dog extends Animal{
constructor(name, age, sex) {
super(name, age)
this.sex = sex
}
}
new Animal()
// error
Uncaught Error: Animal class can`t instantiate
at new Animal (<anonymous>:4:13)
at <anonymous>:1:1
new Dog('mimi', 12, '公')
// Dog {name: "mimi", age: 12, sex: "公"}
然则 java笼统类笼统要领须要重写,这个是没有计划的。因而在测试与运用的历程当中,却不测发明了超类能够在组织时代接见派生类的原型,应用起来。
class Animal {
constructor(name, age) {
console.log(new.target.prototype)
}
// 其他代码
...
}
之前运转时挪用须要重写的要领报错是如许写的。
class Animal {
constructor(name, age) {
this.name = name
this.age = age
}
getName () {
throw new Error('please overwrite getName method')
}
}
class Dog extends Animal{
constructor(name, age, sex) {
super(name, age)
this.sex = sex
}
}
const pite = new Dog('pite', 2, '公')
a.getName()
// error
Uncaught Error: please overwrite getName method
at Dog.getName (<anonymous>:8:11)
at <anonymous>:1:3
但是此时应用 new.target ,我就能够应用 组织时代 对子类举行操纵报错。
class Animal {
constructor(name, age) {
// 假如 target 不是 基类 且 没有 getName 报错
if (new.target !== Animal && !new.target.prototype.hasOwnProperty('getName')) {
throw new Error('please overwrite getName method')
}
this.name = name
this.age = age
}
}
class Dog extends Animal{
constructor(name, age, sex) {
super(name, age)
this.sex = sex
}
}
const pite = new Dog('pite', 2, '公')
// error
Uncaught Error: please overwrite getName method
at new Animal (<anonymous>:5:13)
at new Dog (<anonymous>:14:5)
at <anonymous>:1:1
此时能够把运转要领时刻发作的毛病提前到组织时代,虽然都是在运转期,然则该毛病触发机制要早伤害要大。反而对代码是一种庇护。
固然了,应用超类能够在组织时代接见派生类的原型作用远远不是那末简朴,必定是很壮大的,能够连系营业场景谈一谈明白和作用。
其他计划
增添 编辑器插件
proxy
润饰器