We all know in JS functions generally have two uses, one is as a constructor, one is as a normal function. However, in JS, there is no way to distinguish between the two. Most of the time, we specify that the constructor starts with a capital letter, but this way is artificial, JS is not recognized, so when we call the constructor, accidentally less a new, what will happen? Here’s an example:

function Student(name, score) {
    this.name = name;
    this.score = score;
    this.result = this.name + this.score;
}
console.log(new Student('Ming'.'98'));
console.log(Student('Ming'.'98'));
Copy the code

Output result:

See, when we call the constructor as if it were a normal function, it doesn’t report an error. This is not very friendly. Is there any way to make it report an error? Let’s find out

1, instanceof

What is instanceof for? The instanceof operator is used to check whether the constructor’s prototype property is on the prototype chain of an instance object, or, more commonly, to check whether an object is an instanceof another object. Without further ado, on the code:

function Student(name, score) {
    if(! (this instanceof Student)) {
        throw new TypeError('cannot be invoked without "new"');
    }
    this.name = name;
    this.score = score;
    this.result = this.name + this.score;
}
console.log(new Student('Ming'.'98'));
console.log(Student('Ming'.'98'));
Copy the code

Let’s take a look at the current output:

Okay, so we got an error, we got what we wanted, so let’s go back to this code, this instanceof Student, and if you see this, you don’t panic? I panicked anyway. Calling the constructor with new generates a new object and binds the new object to the this of the calling function. Oops, it’s easy. After the new call, this refers to the instance, and the normal call refers to the window (non-strictly mode, strictly mode refers to undefined). This does make the constructor impossible to call normally.

but

We ignore that the JS call/apply method can change the reference of this. If we can force this to change the reference of this, the above code would be stupid

We fooled JS into thinking we were calling from new. Since there are loopholes in this method, what else can be done? There must be, after all, I’m not the first to find this bug. Keep reading…

2, the new target

The new. Target attribute allows you to detect whether a function or constructor was called using the new operator. In a function or constructor initialized by the new operator, new.target returns a reference to the constructor or function. In normal function calls, the value of new.target is undefined. Yes, it would be great! Try again

After a method, always want to find a method, come, continue ~

3, class

Class specifies that the constructor of a class must be called using new

That’s very comfortable. Okay, I know what you’re asking: “SinceclassYou must use thenew, it willnew.targetWhat are you doing?” , don’t be curious, curious to see the next article, and then want to go bald ~

Did you, uh, fail school?