手寫實(shí)現(xiàn)JS中的new
⚠ 預(yù)備知識(shí):
- 了解原型和原型鏈
- 了解this綁定
1 new 運(yùn)算符簡(jiǎn)介
MDN文檔:new
運(yùn)算符創(chuàng)建一個(gè)用戶定義的對(duì)象類型的實(shí)例或具有構(gòu)造函數(shù)的內(nèi)置對(duì)象的實(shí)例。
class Person { constructor(name) { this.name = name; } } // 創(chuàng)建自定義對(duì)象類型的實(shí)例 const person = new Person('小明') // 創(chuàng)建具有構(gòu)造函數(shù)的內(nèi)置對(duì)象的實(shí)例 const date = new Date()
new的作用:創(chuàng)建對(duì)象的實(shí)例
2 new 究竟干了什么事
上面說了new
的作用是創(chuàng)建對(duì)象的實(shí)例,那么它究竟是怎么創(chuàng)建實(shí)例的,內(nèi)部干了哪幾件事?
以new Person()為例,當(dāng)它執(zhí)行時(shí),會(huì)發(fā)生以下事情:
創(chuàng)建一個(gè)空的簡(jiǎn)單JS對(duì)象
const obj = {}
給這個(gè)對(duì)象添加屬性__proto__,
并將該屬性鏈接到構(gòu)造函數(shù)的原型對(duì)象
obj.__proto__ = Person.prototype
調(diào)用構(gòu)造函數(shù)Person
,并將this
綁定到新創(chuàng)建的對(duì)象obj
Person.apply(obj)
如果構(gòu)造函數(shù)沒有顯式返回一個(gè)對(duì)象,則返回新創(chuàng)建的對(duì)象,即obj
3 模擬實(shí)現(xiàn) new 運(yùn)算符
如上所述,new
運(yùn)算符就干了這么4件事,下面我們就根據(jù)這4個(gè)步驟用函數(shù)來模擬實(shí)現(xiàn)new
(面試手寫代碼)
const _new = function(constructor, ...args) { const obj = {} obj.__proto__ = constructor.prototype const res = constructor.apply(obj, args) // 這一步在"補(bǔ)充"中會(huì)詳細(xì)解釋 return res instanceof Object ? res : obj }
代碼非常簡(jiǎn)單,就是按照上面4步,一步一步寫就可以了
4 補(bǔ)充
ES5
提供了Object.create
方法,該方法可以創(chuàng)建一個(gè)對(duì)象,并讓新對(duì)象的__proto__
屬性指向已經(jīng)存在的對(duì)象。
所以我們可以使用這個(gè)方法合并1、2兩步
const obj = Object.create(constructor.prototype) // 等價(jià)于 const obj = {} obj.__proto__ = constructor.prototype
對(duì)于第4步,再解釋一下
- 如果構(gòu)造函數(shù)沒有顯式
return
(通常情況)那么person
就是新創(chuàng)建的對(duì)象obj
- 如果構(gòu)造函數(shù)返回的不是一個(gè)對(duì)象,比如1、"abc" 那么
person
還是新創(chuàng)建的對(duì)象obj
function Person() { ... return 1 }
如果構(gòu)造函數(shù)顯式返回了一個(gè)對(duì)象,比如{}
、function() {}
那么person
就不是新創(chuàng)建的對(duì)象obj
了,而是顯式return
的這個(gè)對(duì)象
function Person() { // 函數(shù)也是對(duì)象 return function() {} }
所以我們?cè)赺new函數(shù)最后一句代碼是:
return res instanceof Object ? res : obj
注意:模擬實(shí)現(xiàn)的函數(shù)_new傳入的參數(shù)只能是構(gòu)造函數(shù),不能是類
class Animal { ...}_new(Animal)// 會(huì)報(bào)錯(cuò):Class constructor Animal cannot be invoked without 'new'// 類只能通過new來創(chuàng)建
到此這篇關(guān)于手寫實(shí)現(xiàn)JS中的new的文章就介紹到這了,更多相關(guān)JS中的new內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
umi插件開發(fā)仿dumi項(xiàng)目實(shí)現(xiàn)頁(yè)面布局詳解
這篇文章主要為大家介紹了umi插件開發(fā)仿dumi項(xiàng)目實(shí)現(xiàn)頁(yè)面布局詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01微信小程序 頁(yè)面跳轉(zhuǎn)及數(shù)據(jù)傳遞詳解
這篇文章主要介紹了微信小程序 頁(yè)面跳轉(zhuǎn)及數(shù)據(jù)傳遞詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03JS輕量級(jí)函數(shù)式編程實(shí)現(xiàn)XDM二
這篇文章主要為大家介紹了JS函數(shù)式編程實(shí)現(xiàn)XDM示例詳解第2/3篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06axios進(jìn)度條onDownloadProgress函數(shù)total參數(shù)undefined解決分析
這篇文章主要介紹了axios進(jìn)度條onDownloadProgress函數(shù)total參數(shù)undefined解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07微信小程序遇到修改數(shù)據(jù)后頁(yè)面不渲染的問題解決
這篇文章主要介紹了微信小程序遇到修改數(shù)據(jù)后頁(yè)面不渲染的問題解決的相關(guān)資料,需要的朋友可以參考下2017-03-03