詳解 JS 中 new 調用函數原理javascript
Q: 什麼場景下須要使用 new 操做符?
A: 建立一個實例對象java
- "建立" 說明會返回一個全新的(否則這裏就會使用複製等其餘詞彙)
- "對象" 說明返回的類型是對象類型(因此若是 欲返回 基本數據類型的時候,確定會內部處理成某個對象返回)
Q: 爲何要使用 new 操做符?
A: 是爲了 偷懶。使用一個操做符就能夠將一些公共的屬性和方法(Function 構造函數中以及 Function.prototype 中的)一鍵放置到實例對象中。segmentfault
- "Function 構造函數以及 Function.prototype 中的屬性和方法" 說明會運行該 Function 構造函數,並將實例對象的 prototype 置爲 Function.prototype
- "放置到" 說明 這些屬性和方法會綁定到該對象上,也就是「屬於」該對象,因此會重置 this 到當前對象
- "Function..." 那麼就須要一個**「類別標識」**,經過將實例對象的 prototype 置爲 Function.prototype,類型判斷時(instanceof 等)能夠正確反饋類別,方便開發人員進行操做
function isObject(o) {
return Reflect.apply(Object.prototype.toString, o, []) === '[object Object]'
}
function objectFactory() {
const Constructor = [].shift.call(arguments) //獲取構造函數
if (typeof Constructor !== 'function') return new Error('error') //判斷是不是函數,若是不是函數的話,提示錯誤
const objProto = isObject(Constructor.prototype)
? Constructor.prototype
: Object.prototype //判斷Constructor.prototype是否是對象類型(這裏須要注意若是使用typeof判斷的話,null會誤入其中)。若是不是對象的話,這裏會將須要返回的對象的prototype置爲Object.prototype
const obj = Object.create(objProto) //建立對象
const ret = Constructor.apply(obj, arguments) //執行構造函數
return isObject(ret) ? ret : obj //若是構造函數返回對象就返回該對象,不然(無返回或返回不是對象)就返回obj
}
複製代碼