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