JS 中例項必須使用 new 關鍵字生成的寫法
阿新 • • 發佈:2018-12-14
this instanceof xx
在 JS
中一個例項物件的建立必須使用 new
操作符。但是限於 JS
的語法特徵, 實際上 建構函式
同樣可以像普通函式那樣直接執行,這就使用了 函式作為建構函式的意義,為了避免這種情況的發生,很多 JS
庫使用下面的這種方式:
function Person () {
if(!this instanceof Person){
console.warn('should be called with the new !')
}
}
為了瞭解這種方式的原理,我們先要理解當我們使用 new
時做了些什麼。
當時用 new
操作符的時候,實際上會經歷以下 4 個步驟:
- 建立一個新的物件。
- 將建構函式的作用域賦值給這個新物件。(this 指向該物件)。
- 執行建構函式中的程式碼。
- 返回新物件。
在執行了這四個步驟後,除了將作用域賦值給了新的物件,還將 夠建構函式的 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 !')
}
}
}