函数内部有两个方法 [[call]] 和 [[construct]] (箭头函数没有这个方法),当使用new 操作符时, 函数内部调用 [[construct]], 创建一个新实例,this指向这个实例; 不使用new 操作符时, 函数内部调用 [[call]]。
判断一个函数是否使用new操作符,ES5的方法:
function Person(name) { if (this instanceof Person) { this.name = name; } else { throw new Error("You must use new operator"); } } var p = new Person("James"); // ok var p = Person("James"); // error // 但是可以通过其他方式绕过这种错误 var notPerson = Person.call(p, "Nicholas"); // works
ES6 通过new.target 来判断是否使用new,元属性 是指一个提供目标相关额外信息(比如new)的非对象属性。
function Person(name) { if (typeof new.target !== "undefined") { this.name = name; } else { throw new Errow("You must use new operator"); } } var p = new Person("James"); // ok var notPerson = Person.call(p, "Louis"); // error