JS 中实例必须使用 new 关键字生成的写法

this instanceof xx

JS 中一个实例对象的创建必须使用 new 操作符。但是限于 JS 的语法特征, 实际上 构造函数 同样可以像普通函数那样直接执行,这就使用了 函数作为构造函数的意义,为了避免这种情况的发生,很多 JS 库使用下面的这种方式:

function Person () {
	if(!this instanceof Person){
		console.warn('should be called with the new !')
	}
}

为了了解这种方式的原理,我们先要理解当我们使用 new 时做了些什么。
当时用 new 操作符的时候,实际上会经历以下 4 个步骤:

  1. 创建一个新的对象。
  2. 将构造函数的作用域赋值给这个新对象。(this 指向该对象)。
  3. 执行构造函数中的代码。
  4. 返回新对象。

在执行了这四个步骤后,除了将作用域赋值给了新的对象,还将 够构造函数的 prototype 赋值给了 实例的 __proto__,最终:

let person1 = new Person()
person1.__proto__ === Person.prototype  //true
person instanceof Person  // true 

a instanceof A 用来检测 用来检测a 是否是 A 的实例

class new.target 属性

ES6 中,我们可以使用 class 关键词创建一个 类,每一个 class 类都有一个 new.target 属性,返回 new 命令所作用的构造函数。如果构造函数不是通过 new 操作符调用的, 那么 new.target 会返回 undefined , 因此这个属性同样可以确保 构造函数必须是通过 new 调用的。

function Person () {
	if(new.target !== Person){
		console.warn('should be called with the new !')
	}
}

class Person {
	constructor(){
		if(new.target !== Person){
			throw new Error('should be called with the new !')
		}
	}
}

猜你喜欢

转载自blog.csdn.net/starleejay/article/details/82974030