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