摘要:案例挺簡單,但是改過程有些曲折,在此分享一下在改過程中的自我懷疑自我否定直到曲徑通幽的心路歷程。首先來到我腦海的原因是自執(zhí)行函數的執(zhí)行順序,是否有異步一說。這個問題其實是一個小問題導致的,無關乎技巧。
最近在學習JavaScript中的閉包,涉及到其中一個案例,想著改寫一下。案例挺簡單,但是改bug過程有些曲折,在此分享一下在改bug過程中的自我懷疑自我否定直到曲徑通幽的心路歷程。
需求說明:我們知道arguments對象如果想調用Array的push方法,需要使用Array.prototype.push.apply(argument,[1,2])這樣的方式,但每次都寫這么一長串代碼特別繁瑣,想著提取一個push方法,方便以后直接調用。
廢話不多說,,直接貼代碼。
//提取的方法 var push = (function(){ return function(){ var obj = Array.prototype.shift.apply(arguments); Array.prototype.push.apply(obj,arguments); return arguments; } })()
方法洋洋灑灑寫完之后,進入自測階段。為了偷懶,再次使用了自執(zhí)行函數,代碼如下:
//自測代碼 (function(){ push(arguments,4) console.log(arguments); })(1,2,3)
在node環(huán)境中執(zhí)行,結果拋錯如下:
Array.prototype.push.apply(obj,arguments); ^ TypeError: Cannot assign to read only property "length" of function "function (){ push(arguments,4) console.log(arguments); }"
這個報錯很明顯,當給一個function調用Array.porotype.push方法時會拋出這樣的錯誤,因為一個function的length屬性是只讀的,而push的源碼中l(wèi)ength屬性是需要可以修改的,即一個對象具有可讀寫的length屬性之后才可以調用Array.porototype.push方法。
回到我提取的push方法中分析,Array.prototype.push.apply(obj,arguments);此刻我的obj應該是一個類數組{ "0": 1, "1": 2, "2": 3 },所以報錯提示無法直觀解決問題。
首先為了排除測試案例的原因,我修改了我的測試案例,避免function的介入,代碼如下:
//測試案例 var fn = function(){ push(arguments,4); console.log(arguments); } fn(1,2,3);
修改完成之后發(fā)現測試順利通過,說明我提取的方法沒有問題。到此,牽扯出了一個新問題,我使用自執(zhí)行函數時為啥會導致出錯。
首先來到我腦海的原因是自執(zhí)行函數的執(zhí)行順序,是否有異步一說。因為我提取push方法也是用的自執(zhí)行函數,測試案例也是自執(zhí)行函數,有可能兩自執(zhí)行函數的先后執(zhí)行順序導致了問題,為了驗證這個答案,我決定將自測案例延時執(zhí)行,代碼如下:
setTimeout(function(){ (function(){ push(arguments,4) console.log(arguments); })(1,2,3) },10);
測試發(fā)現順利通過,這個測試結果更加懷疑了剛才的假設(雖然心里一萬個不相信)。然后開始查js自執(zhí)行函數的執(zhí)行順序的問題,未果,說明大家都沒遇到這樣的問題,那很有可能我這假設不對。沒辦法,只能繼續(xù)修改測試,既然是因為調用push.apply時候出錯,我先注釋掉它試試。代碼如下:
//提取方法代碼 var push = (function(){ return function(){ var obj = Array.prototype.shift.apply(arguments); // Array.prototype.push.apply(obj,arguments); return arguments; } })() //測試案例代碼 (function(){ // push(arguments,4) console.log(arguments); })(1,2,3)
運行結果,拋出了不一樣的錯誤,不一樣的煙花,錯誤如下
D:githubjsStudyheightFn.js:174 })(1,2,3) ^ TypeError: (intermediate value)(...)(...) is not a function
這個錯誤提示很容易定位到了問題,自執(zhí)行函數結尾未寫分號導致。
這個問題其實是一個小問題導致的,無關乎技巧。分享這個主要是想表達:在遇到問題時,我們看到的問題可能只是表象,尋找解決方案的過程就是一個不斷自我猜想,驗證猜想,不斷否定的過程,需要持續(xù)不斷的挖掘。
最后貼出最終代碼:
var push = (function(){ return function(){ var obj = Array.prototype.shift.apply(arguments); Array.prototype.push.apply(obj,arguments); return arguments; } })(); //測試案例 ;(function(){ push(arguments,4) console.log(arguments); })(1,2,3);
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/94018.html
摘要:刪除不必要的代碼。而簡化前的代碼包含的語法要素對于傳達代碼意義本身作用并不大。刪除不必要的代碼有時候,我們試圖為不必要的事物命名。例如,大多數情況下,你應該省略僅僅用來當做返回值的變量。你的函數名應該已經說明了關于函數返回值的信息。 原文地址 本文已在前端早讀課公眾號首發(fā):【第952期】JavaScript代碼風格要素 譯者:墨白 校對:野草 1920年,由威廉·斯特倫克(Will...
摘要:為這些回調函數分別命名并分離存放可以在形式上減少嵌套,使代碼清晰,但仍然不能解決問題。如果在一個結束成功或失敗,同前面的說明后,添加針對成功或失敗的回調,則回調函數會立即執(zhí)行。 異步? 我在很多地方都看到過異步(Asynchronous)這個詞,但在我還不是很理解這個概念的時候,卻發(fā)現自己常常會被當做已經很清楚(* ̄? ̄)。 如果你也有類似的情況,沒關系,搜索一下這個詞,就可以得到大致...
摘要:壞的命名方式好的命名方式避免使用過多參數。你只需要在每一個函數的末尾返回,之后的代碼會更加的簡潔。在很多情況下,你可能搞出重復代碼。自從年雙十一正式上線,累計處理了億錯誤事件,付費客戶有金山軟件百姓網等眾多品牌企業(yè)。 譯者按: 簡潔的代碼可以避免寫出過多的BUG。 原文: JavaScript Clean Code - Best Practices 譯者: Fundebug ...
閱讀 3026·2021-11-24 09:39
閱讀 2256·2021-10-08 10:05
閱讀 2749·2021-09-24 13:52
閱讀 1569·2021-09-22 15:07
閱讀 589·2019-08-30 15:55
閱讀 1808·2019-08-30 15:53
閱讀 687·2019-08-30 15:44
閱讀 3116·2019-08-30 11:20