摘要:第二例這段代碼是用來(lái)做將斷言測(cè)試分組的,代碼多了些,問題自然也更多了些。首先作者使用了自執(zhí)行方法封閉了作用域,使用來(lái)指向全局對(duì)象,進(jìn)而產(chǎn)生全局可訪問的屬性。沒想到,久負(fù)盛名,豆瓣評(píng)分的大作,作者的光環(huán),代碼風(fēng)格居然是如此的不謹(jǐn)慎。
第一例:第二章中 作者給了幾個(gè)簡(jiǎn)單的斷言例子,思路與方向是極不錯(cuò)的,創(chuàng)造JQ的大神,思想高度絕對(duì)無(wú)法讓我質(zhì)疑的,但是代碼的功底細(xì)節(jié),實(shí)在是讓人不敢恭維。
function assert(value, desc) { var li = document.createElement("li"); li.className = value ? "pass" : "fail"; li.appendChild(document.createTextNode(desc)); //為何不直接使用textContent進(jìn)行文本賦值呢?相比下,性能會(huì)更好! document.getElementById("result").appendChild(li); //每次執(zhí)行斷言 都要重新動(dòng)態(tài)查找一次result節(jié)點(diǎn)? } assert(true, "這是真幣!"); assert(false, "這是假幣@");
上述書中案例,我從雞蛋里挑骨頭,選了兩處不妥之處,一個(gè)是反復(fù)查找節(jié)點(diǎn)無(wú)緩存,另一個(gè)是文本節(jié)點(diǎn)創(chuàng)造的低效率。
改造代碼:var assert = (function () { //通過閉包 緩存斷言的根ul節(jié)點(diǎn) var results = document.getElementById("result"); return function (value, desc) { var li = document.createElement("li"); li.className = value ? "pass" : "fail"; //使用textContent屬性插入文本節(jié)點(diǎn) 提高效率 li.textContent = desc; results.appendChild(li); }; })();
上面的代碼改善了書里的小遺漏,仍然不夠完美,因?yàn)槌跏嫉亩栊约虞d,會(huì)有額外的性能損耗,下面再提供兩種極改善方案。
function getAssert() { //取消惰性加載 var results = document.getElementById("result"); return function (value, desc) { var li = document.createElement("li"); li.className = value ? "pass" : "fail"; li.textContent = desc; results.appendChild(li); }; }; //需要初始拿到返回方法 var assert = getAssert(); assert(true, "這是真幣!"); assert(false, "這是假幣@");
上面這一則,取消了惰性加載,但是需要手動(dòng)獲取返回的方法。
下面使用重載:
var assert = function(value,desc) { //保留作用域 緩存私有變量results var results = document.getElementById("result"); //重賦值 assert = function (value, desc) { var li = document.createElement("li"); li.className = value ? "pass" : "fail"; li.textContent = desc; results.appendChild(li); }; //第一次調(diào)用 手動(dòng)調(diào)用 assert(value,desc); }; assert(true, "這是真幣!"); assert(false, "這是假幣@");
第二例世界清靜了,代碼終于看似完美了。但實(shí)際的需求里,可能我們要將方法封閉起來(lái),讓同事或者用戶使用,那么results這個(gè)id,就有了相當(dāng)大的局限性了,fail與pass的類名也不夠靈活。這個(gè)場(chǎng)景下,我們更應(yīng)該使用再往上一個(gè)的方式,可以給與我們更大的diy空間。
(function () { var results; this.assert = function (value, desc) { var li = document.createElement("li"); li.className = value ? "pass" : "fail"; results.appendChild(li); if (value) { li.parentNode.parentNode.className = "fail"; } return li; }; this.test = function (name, fn) { results = document.getElementById("results"); results = assert(true, name).appendChild( document.createElement("ul"); ) fn(); }; });
這段代碼是用來(lái)做將斷言測(cè)試分組的,代碼多了些,問題自然也更多了些。
首先作者使用了自執(zhí)行方法封閉了作用域,使用this來(lái)指向全局對(duì)象,進(jìn)而產(chǎn)生全局可訪問的屬性。
但這段代碼是有著執(zhí)行缺陷的,assert方法可以在test方法外調(diào)用,那么此時(shí)results是根級(jí)ul,還是分組Ul呢?而且動(dòng)態(tài)查找節(jié)點(diǎn)的問題依舊沒有改動(dòng)。
代碼改善:var global = (function () { //嚴(yán)格模式下全局的this 無(wú)法訪問 在此做一個(gè)防御措施 return this ? this : window; })(); (function (global) { //緩存根root節(jié)點(diǎn) var rootResults = document.querySelector(".test-root"), results; // 將assert私有化 外部不得訪問 function assert(value, desc) { var domLi = document.createElement("li"); domLi.className = value ? "pass" : "fail"; domLi.textContent = desc; results.appendChild(domLi); if (!value) { domLi.parentNode.parentNode.className = "fail"; } return domLi; }; global.test = function (name, fn) { results = rootResults; results = assert(true, name).appendChild( document.createElement("ul") ); //回調(diào)函數(shù)可以從參數(shù)里調(diào)用assert fn(assert); } })(global);
重復(fù)了緩存DOM節(jié)點(diǎn)的操作,為this的指向做出回退機(jī)制,私有化assert方法,將assert方法入?yún)⒌絫est方法的回調(diào)方法中,算是勉強(qiáng)完美了。
沒想到,久負(fù)盛名,豆瓣評(píng)分8+的大作,JQ作者的光環(huán),代碼風(fēng)格居然是如此的不謹(jǐn)慎。暫待我往下閱讀,期望能夠有打臉回饋。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/89580.html
摘要:無(wú)處不在的理解語(yǔ)言與其他主流語(yǔ)言相比,函數(shù)式語(yǔ)言的血統(tǒng)更多一些。函數(shù)式語(yǔ)言一類程序設(shè)計(jì)語(yǔ)言,是一種非馮諾伊曼式的程序設(shè)計(jì)語(yǔ)言。函數(shù)式語(yǔ)言主要成分是原始函數(shù),定義函數(shù)和函數(shù)型。性能分析內(nèi)置對(duì)象上的和方法。 無(wú)處不在的JavaScript 理解JavaScript語(yǔ)言 與其他主流語(yǔ)言相比,JavaScript函數(shù)式語(yǔ)言的血統(tǒng)更多一些。 函數(shù)式語(yǔ)言一類程序設(shè)計(jì)語(yǔ)言,是一種非馮.諾伊曼式的程序...
摘要:閉包閉包的特點(diǎn)就是內(nèi)部匿名函數(shù)可以訪問外部函數(shù)作用域的變量和方法變量對(duì)象。閉包的主要表現(xiàn)形式就是匿名函數(shù),但是兩者并不是等價(jià)的。中是沒有塊級(jí)作用域的,為了在中引入塊級(jí)作用域,可以使用匿名函數(shù)模擬塊級(jí)作用域。 在介紹閉包之前,首先解釋在隨后的測(cè)試實(shí)例中會(huì)使用的assert測(cè)試函數(shù),這個(gè)方法有別于alert()測(cè)試,有很大的改進(jìn)。 assert()測(cè)試方法 #...
摘要:閉包閉包的特點(diǎn)就是內(nèi)部匿名函數(shù)可以訪問外部函數(shù)作用域的變量和方法變量對(duì)象。閉包的主要表現(xiàn)形式就是匿名函數(shù),但是兩者并不是等價(jià)的。中是沒有塊級(jí)作用域的,為了在中引入塊級(jí)作用域,可以使用匿名函數(shù)模擬塊級(jí)作用域。 在介紹閉包之前,首先解釋在隨后的測(cè)試實(shí)例中會(huì)使用的assert測(cè)試函數(shù),這個(gè)方法有別于alert()測(cè)試,有很大的改進(jìn)。 assert()測(cè)試方法 #...
摘要:設(shè)置和清除定時(shí)器直接引用忍者秘籍中的圖片注意定時(shí)器的時(shí)間間隔設(shè)為,也會(huì)有幾毫秒的延遲。以上參考資料忍者秘籍第章馴服線程和定時(shí)器 showImg(https://segmentfault.com/img/remote/1460000015353524?w=1024&h=681); 前言 前段時(shí)間剛看完《JS忍者秘籍》,雖說(shuō)是15年出版的,有些東西是過時(shí)了,但像對(duì)原型鏈、閉包、正則、定時(shí)器...
摘要:我們需要知道的是,對(duì)于而言,匿名函數(shù)是一個(gè)很重要且具有邏輯性的特性。通常,匿名函數(shù)的使用情況是創(chuàng)建一個(gè)供以后使用的函數(shù)。截圖自忍者秘籍通過完善之前對(duì)匿名函數(shù)的粗略定義,我們可以修復(fù)解決這個(gè)問題。 從名字即可看書,此篇博客總結(jié)與《JavaScript忍者秘籍》。對(duì)于JavaScript來(lái)說(shuō),函數(shù)為第一類型對(duì)象。所以這里,我們主要是介紹JavaScript中函數(shù)的運(yùn)用。 系列博客地址:h...
閱讀 1877·2023-04-25 22:42
閱讀 2245·2021-09-22 15:16
閱讀 3512·2021-08-30 09:44
閱讀 511·2019-08-29 16:44
閱讀 3339·2019-08-29 16:20
閱讀 2539·2019-08-29 16:12
閱讀 3410·2019-08-29 16:07
閱讀 694·2019-08-29 15:08