origin
Recently, when Symbol was used as a unique value, it was found that Symbol can't do the new operation, it can only be used as a function, and type errors will occur whenever new is used
new Symbol() // error Uncaught TypeError: Symbol is not a constructor at new Symbol (<anonymous>) at <anonymous>:1:1
Regardless of the underlying implementation, can you implement a function at the code level that can only be called without a new operation?After thinking, write the following:
function disConstructor() { if (this !== window) { throw new TypeError(' disConstructor is not a constructor') } console.log('gogo go') } // The test results are as follows disConstructor() // gogo go new disConstructor() // error Uncaught TypeError: disConstructor is not a constructor at new disConstructor (<anonymous>:3:15) at <anonymous>:1:1
With nodejs, windows can switch to global, and the results of the code run unchanged because there are no scenarios for individuals.So there's no further research going on, but we recently discovered the new.target property when we flipped through es6.
new.target property
Introduction (referencing mdn documents)
The new.target property allows you to detect whether a function or construction method is called through the new operator.
In a function or construction method initialized by the new operator, new.target returns a reference to the construction method or function.In normal function calls, the value of new.target is undefined.
That way, our code can be changed to
function disConstructor() { // In normal function calls, the value of new.target is undefined. if (new.target) { throw new TypeError(' disConstructor is not a constructor') } console.log('gogo go') }
Get the same answer as the code above.
thorough
Can es6 specifically add functionality only to check how we call functions?
During the lookup process, various discoveries found that most scenarios use new.target to write out classes that can only be inherited.Similar to abstract classes that implement java.
class Animal { constructor(name, age) { if (new.target === Animal) { throw new Error('Animal class can`t instantiate'); } this.name = name this.age = age } // Other Codes ... } 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, 'common') // Dog {name:'mimi', age: 12, sex:'public'}
However, java abstract class abstract methods need to be overridden, which is schemaless.Thus, in the process of testing and using, it is unexpected to find that superclasses can access the prototype of derived classes during construction and use them.
class Animal { constructor(name, age) { console.log(new.target.prototype) } // Other Codes ... }
This was the case with method errors previously invoked by the runtime that needed to be overridden.
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, 'common') a.getName() // error Uncaught Error: please overwrite getName method at Dog.getName (<anonymous>:8:11) at <anonymous>:1:3
However, with new.target at this point, I can use the construction time to make operational errors on subclasses.
class Animal { constructor(name, age) { // If the target is not a base class and there is no getName error 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, 'common') // error Uncaught Error: please overwrite getName method at new Animal (<anonymous>:5:13) at new Dog (<anonymous>:14:5) at <anonymous>:1:1
Errors that occur while running a method can be advanced to the construction period at this time, although they are all in the run time, but the error triggering mechanism is more harmful early.Instead, it protects the code.
Of course, using superclasses to access the prototype role of derived classes during construction is far from simple, it must be powerful, and you can talk about understanding and role in conjunction with business scenarios.
Other options
Add Editor Plug-in
proxy
Decorator