摘要:為啥我要自己實現(xiàn)一個語法糖為什么要自己實現(xiàn)一個語法糖呢因為之前對于里的語法糖一直是理論理解但是并親自嘗試實現(xiàn)過。直到有一天在頭條的面試中我聊了摸著自己的良心說我可以實現(xiàn)一個語法糖面試官嗯那你實現(xiàn)一個吧。我們知道構(gòu)造函數(shù)一般是不寫的。
為啥我要自己實現(xiàn)一個new語法糖?
為什么要自己實現(xiàn)一個new語法糖呢?
因為之前對于JS里的new語法糖一直是理論理解,但是并親自嘗試實現(xiàn)過。
直到有一天,在頭條的面試中 我聊high了,摸著自己的良心說: 我可以實現(xiàn)一個new語法糖!
面試官: 嗯,那你實現(xiàn)一個吧。
我: ...咱要不聊點別的?
步驟1: 觀察new做了哪些事?先隨便用一下new,然后觀察、腦補、想象,最后猜一下new可能干了點什么勾當(dāng)!
function Human(){ this.type = "human" this.age = 18 } var human1 = new Human() console.log(h1) // {type:"human",age:18}
掐指一算,先不管怎么做,直覺上new大概做了這樣幾件事情
創(chuàng)建一個空對象
讓空對象的__proto__指向構(gòu)造函數(shù)的prototype,并且this指向這個對象
偷偷return這個對象
function Human(){ // var obj = {} 創(chuàng)建了一個空對象 // obj.__proto__ = Human.prototype 讓空對象的__proto__指向構(gòu)造函數(shù)的prototype // this = obj obj賦值給this this.type = "human" this.age = 18 // return this 偷偷幫你return這個對象 } var human1 = new Human() console.log(h1) // {type:"human",age:18}步驟2: 設(shè)計一下接口
面向接口編程嘛,設(shè)計一個程序,先思考最后是以什么形式調(diào)用呢? 畢竟我們不是JS之父,沒法真的去創(chuàng)造語法。
我們打算封裝一個函數(shù)newFn(),可以用來創(chuàng)建實例對象,然后它最終是這樣來用的:
下面是偽代碼
function Human(){ this.type = "human" this.age = 18 } // var human1 = new Human() 不用new了,我們用newFn()來創(chuàng)建實例 function newFn(){ ... 寫一些代碼 } var human1 = newFn(Human)步驟3: 實現(xiàn)newFn()
那么newFn()的輸入和輸出是什么呢?
參數(shù): Constructor和數(shù)量不定的參數(shù)。我們肯定得知道是創(chuàng)造哪個構(gòu)造函數(shù)的實例吧,所以至少需要一個Constructor,同時也可以自定義一些參數(shù)
返回: 返回一個obj,也即是構(gòu)造函數(shù)的實例
function newFn() { const obj = {}; const Constructor = [].shift.call(arguments) // 通過arguments取出第一個參數(shù) Constructor ,并截取掉arguments第一個參數(shù),方便之后使用 obj.__proto__ = Constructor.prototype; // 讓這個obj繼承一下Constructor原型鏈上的東西 Constructor.apply( obj, arguments ) // 這里是obj借用一下Constructor這個方法,從而給obj添加type 和 age return obj // 返回對象 } 注: shift() 方法用于把數(shù)組的第一個元素從其中刪除,并返回第一個元素的值。
Example: 使用newFn去創(chuàng)造一個實例 (可以拿到瀏覽器測試用)
function newFn() { const obj = {}; const Constructor = [].shift.call(arguments) obj.__proto__ = Constructor.prototype; Constructor.apply( obj, arguments ) return obj } function Human() { this.type = "human" this.age = 18 } var human1 = newFn( Human ) console.log( human1 )
可以發(fā)現(xiàn)human1這個實例,跟我們用new語法創(chuàng)造出來的是一個效果。
小小的補充修改為了讓newFn跟new的行為表現(xiàn)更加相似,需要做一點點修改完善。
我們知道,構(gòu)造函數(shù)一般是不寫return的。它偷偷自動給你return一個實例對象
但是如果,我們手動return呢? 2個情況
return 了一個基本數(shù)據(jù)類型,不會返回這個簡單數(shù)據(jù)類型, 依舊幫你return一個實例對象
return 了一個對象,那么就返回你這個對象。不再幫你return實例對象
所以,為了實現(xiàn)同樣的效果,newFn修改一行代碼
function newFn() { const obj = {}; const Constructor = [].shift.call(arguments) obj.__proto__ = Constructor.prototype; const result = Constructor.apply( obj, arguments ) // 接受一下構(gòu)造函數(shù)的返回值,是對象就return該對象,否則還是return實例對象 return typeof result === "object" ? result : obj }
Example: 使用完善后的newFn去創(chuàng)造一個實例 (可以拿到瀏覽器測試用)
function newFn() { const obj = {}; const Constructor = [].shift.call( arguments ) obj.__proto__ = Constructor.prototype; const result = Constructor.apply( obj, arguments ) // 接受一下構(gòu)造函數(shù)的返回值,是對象就return該對象,否則還是return實例對象 return typeof result === "object" ? result : obj } function Human( name, age ) { this.type = "human" this.age = 18 return { name: name, age: age } } var human1 = newFn( Human, "ziwei", "24" ) console.log( human1 )
更多文章,可關(guān)注https://github.com/ziwei3749/...
如果有疑問或者發(fā)現(xiàn)錯誤,可以在相應(yīng)的 issues 進(jìn)行提問或勘誤。
如果喜歡或者有所啟發(fā),歡迎 star,對作者也是一種鼓勵。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/94353.html
摘要:本文首發(fā)于的技術(shù)博客實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。只是最近學(xué)習(xí)生態(tài),用起來轉(zhuǎn)換之余,也不免碰到諸多用上的教程案例,因此便稍作學(xué)習(xí)。在當(dāng)前的瀏覽器市場下,想在生產(chǎn)環(huán)境用上,是必不可少的。 本文首發(fā)于Array_Huang的技術(shù)博客——實用至上,非經(jīng)作者同意,請勿轉(zhuǎn)載。原文地址:https://segmentfault.com/a/1190000006992218如果您對本系列文章感興...
摘要:首先為了模擬類創(chuàng)建對象的功能搞出了構(gòu)造函數(shù)。也就是名字膚色膚色這里是繼承里的自有屬性生命值這里繼承的共有屬性的方法攻擊力兵種美國大兵攻擊防御死亡膚色 JS面向?qū)ο笾?【繼承】 我們已經(jīng)準(zhǔn)備了很多前置知識,包括 原型鏈,對象和對象之間的關(guān)系 this,對象和函數(shù)之間的關(guān)系 new, 用函數(shù)批量創(chuàng)建特定的對象的語法糖 JS面向?qū)ο蟮那笆澜裆?我們說,面向?qū)ο笫且环N寫代碼的套路。因為如...
摘要:但其實,虛擬機(jī)并不支持這些語法糖。方式為每個泛型類型創(chuàng)建唯一的字節(jié)碼表示,并且將該泛型類型的實例都映射到這個唯一的字節(jié)碼表示上。GitHub 2.5k Star 的Java工程師成神之路 ,不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的確定不來了解一下嗎); 本文從 ...
摘要:但其實,虛擬機(jī)并不支持這些語法糖。方式為每個泛型類型創(chuàng)建唯一的字節(jié)碼表示,并且將該泛型類型的實例都映射到這個唯一的字節(jié)碼表示上。GitHub 2.5k Star 的Java工程師成神之路 ,不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的確定不來了解一下嗎); 本文從 ...
摘要:但其實,虛擬機(jī)并不支持這些語法糖。方式為每個泛型類型創(chuàng)建唯一的字節(jié)碼表示,并且將該泛型類型的實例都映射到這個唯一的字節(jié)碼表示上。GitHub 2.5k Star 的Java工程師成神之路 ,不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的不來了解一下嗎); GitHub 2.5k Star 的Java工程師成神之路 ,真的確定不來了解一下嗎); 本文從 ...
閱讀 1217·2021-09-03 10:44
閱讀 617·2019-08-30 13:13
閱讀 2808·2019-08-30 13:11
閱讀 1976·2019-08-30 12:59
閱讀 1043·2019-08-29 15:32
閱讀 1608·2019-08-29 15:25
閱讀 1003·2019-08-29 12:24
閱讀 1290·2019-08-27 10:58