1. 程式人生 > >JS 中例項必須使用 new 關鍵字生成的寫法

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 !') } } }