字節(jié):如何模擬實現(xiàn) new 操作符
點(diǎn)擊上方 前端瓶子君,關(guān)注公眾號
回復(fù)算法,加入前端編程面試算法每日一題群
https://mp.weixin.qq.com/s/2elzsKW1uqVsp05QTuK0Kg
new 運(yùn)算符創(chuàng)建一個用戶定義的對象類型的實例或具有構(gòu)造函數(shù)的內(nèi)置對象的實例。new 關(guān)鍵字會進(jìn)行如下的操作:
創(chuàng)建一個空的簡單JavaScript對象(即 {});鏈接該對象(即設(shè)置該對象的構(gòu)造函數(shù))到另一個對象 ; 將步驟1新創(chuàng)建的對象作為 this的上下文 ;如果該函數(shù)沒有返回對象,則返回 this。
代碼實現(xiàn):
function new_object() {
// 創(chuàng)建一個空的對象
let obj = new Object()
// 獲得構(gòu)造函數(shù)
let Con = [].shift.call(arguments)
// 鏈接到原型 (不推薦使用)
obj.__proto__ = Con.prototype
// 綁定 this,執(zhí)行構(gòu)造函數(shù)
let result = Con.apply(obj, arguments)
// 確保 new 出來的是個對象
return typeof result === 'object' ? result : obj
}
警告: 通過現(xiàn)代瀏覽器的操作屬性的便利性,可以改變一個對象的
[[Prototype]]屬性, 這種行為在每一個JavaScript引擎和瀏覽器中都是一個非常慢且影響性能的操作,使用這種方式來改變和繼承屬性是對性能影響非常嚴(yán)重的,并且性能消耗的時間也不是簡單的花費(fèi)在obj.__proto__ = ...語句上, 它還會影響到所有繼承來自該[[Prototype]]的對象,如果你關(guān)心性能,你就不應(yīng)該在一個對象中修改它的 [[Prototype]]。相反, 創(chuàng)建一個新的且可以繼承[[Prototype]]的對象,推薦使用Object.create()—MDN
所以進(jìn)一步優(yōu)化 new 實現(xiàn):
// 優(yōu)化后 new 實現(xiàn)
function create() {
// 1、獲得構(gòu)造函數(shù),同時刪除 arguments 中第一個參數(shù)
Con = [].shift.call(arguments);
// 2、創(chuàng)建一個空的對象并鏈接到原型,obj 可以訪問構(gòu)造函數(shù)原型中的屬性
let obj = Object.create(Con.prototype);
// 3、綁定 this 實現(xiàn)繼承,obj 可以訪問到構(gòu)造函數(shù)中的屬性
let ret = Con.apply(obj, arguments);
// 4、優(yōu)先返回構(gòu)造函數(shù)返回的對象
return ret instanceof Object ? ret : obj;
};
來自:https://github.com/sisterAn/JavaScript-Algorithms
最后
評論
圖片
表情
