JavaScript模式讀書筆記 第4章 函數
2014年11月10日
1,JavaScript函數具有兩個特點: 函數是第一類對象 函數可以提供範圍 函數即對象,表現為:
-1,函數可以在運行時動態建立,也可以在程式執行過程中建立。
-2,函數可以分配給變數,可以將它們的引用複製到其他變數,可以被擴充,此外,函數還可以被刪除。
-3,可以做為參數傳遞給其他函數,,還可以由其他函數返回。
-4,函數可以有自己的屬性和方法。
2,聲明VS運算式:名稱和變數聲明提升
//這是一個函數運算式//它做為一個參數傳遞給函數 CallMecallMe(function(){ //這是命名函數運算式 //也被稱作匿名函數});//這是命名函數運算式callMe(function me(){ //這裡是命名函數運算式 //並且其名稱為me});//另一個函數運算式var myobject = { say:function(){ //這裡是函數運算式 }};
3,函數的提升 對於所有的變數,不管在函數體的何處聲明,都會在後台被提升到函數頂部。4,回調模式
<script> function writeCode(callBack){console.log("callBanck before.....");callBack();console.log("callBanck after....."); } function callBack(){console.log("callBanck .........."); } writeCode(callBack); </script>//輸出結果 callBanck before..... test1.html:14 callBanck .......... test1.html:21 callBanck after.....
如下,展示了一個複雜的查詢DOM節點,然後再在回呼函數中依次進行業務處理。耗時為2n
<script>//尋找節點 var findNodes = function(){var i = 100000,//複雜迴圈 nodes[],//儲存本次運行結果found;//零時儲存找到的節點while(i){//商務邏輯處理//....found = 1;i -= 1;nodes.push(found);}return nodes; }; //對節點處理 var hide = function(nodes){var i = 0, max = nodes.length;for(; i < max; i += 1){//複雜商務邏輯處理console.log(nodes[i]);} }; //執行函數 hide(findNodes()); </script>
<script>var findNodes = function(callBack){var i = 10000, nodes = [],dound;//檢查回呼函數是否為可調用if(typeof callBack != "function"){callBack = false;} while(i){i -= 1; //邏輯處理 。。。。。。。。 //運行回呼函數if(callBack){callBack(found);}nodes.push[found];}return nodes;}; var hide = function(node){//對node節點進行對應的業務處理}; findNodes(hide); </script>
5,閉包 閉包特性,簡而言之就是範圍。
6,自訂函數 -1,如果一個函數重新定義,則會覆蓋原有函數。
var scareMe = function(){console.log("FIRST!");scareMe = function(){console.log("SECOND!");}; }; scareMe(); scareMe();輸出結果:
日誌: FIRST! 日誌: SECOND!
該模式的確定是,當他重定義自身時,已經添加到原始函數的任何屬性都會丟失。此外,如果該函數使用了不同的名稱,比如分配給不同的變數或者以對象的方法來使用,那麼重定義的部分將永遠不會發生,並且將會只i系那個原始函數體。
<script> var scareMe = function(){console.log("FIRST!");scareMe = function(){console.log("SECOND!");}; };//添加新的屬性scareMe.property = "property";//賦值給另一個不同名稱的變數var prank = scareMe; //在一個方法裡使用var spooky = {boo: scareMe}; prank();// firstprank();//firstconsole.log(prank.property);//property spooky.boo();//firstspooky.boo();//firstconsole.log(spooky.boo.property);//property //使用自訂函數scareMe();//secondscareMe();//secondconsole.log(scareMe.property);//undefined </script> 輸出結果: FIRST! test5.html:14 property test5.html:332 FIRST! test5.html:14 property test5.html:372 SECOND! test5.html:17 undefined
7,即時函數 即時函數,定義函數後立即執行該函數的文法。例子如下:
(function(){ alert("One");}());
該模式由以下部分組成: -1,可以使用函數運算式定義一個函數。
-2,在末尾添加一組括弧,這將導致該函數立即執行。
-3,將整個函數封裝在括弧中。該模式一般用於初始化時候,執行一些頁面載入的任務。在初始化完成後就不需要這些變數。可以完全替代以全域變數形式建立的代碼。如下代碼就不會建立過多的全域變數。
<script> (function(){var days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],today = new Date(),msg = "Today is " + days[today.getDay()] + "," + today.getDate();alert(msg); }()); </script>
即時函數的參數
(function(who, how){console.log("i'm " + who + ",I'm " + how); }("pengke", "shabi"));
即時函數的返回值,如下代碼,result指向函數的返回值4。
var result = (function(){ return 2 +2 ;})();
8,函數屬性——備忘模式 可以對函數的參數進行緩衝處理 9,設定物件 適用於一個方法,我們不確定它有多少個參數的情況。 -1,不需要記住眾多的參數以及其順序。 -2,可以安全忽略選擇性參數
-3,更加易於閱讀和維護
-4,更加易於添加和刪除參數
<script>function addPerson(conf){console.log(conf.first);console.log(conf.second);console.log(conf);}var conf = {first: "abc",second: "a",third: "c"};addPerson(conf); </script>10,函數應用 可以使用方法Function.prototype.apply().
<script>//定義函數 var sayHi = function(who){console.log("Hello " + (who ? "," + who : "") + "!"); };sayHi();sayHi('world');sayHi.apply(null, ["world"]); </script>
執行結果Hello ! test10.html:15Hello ,world! test10.html:15Hello ,world!
apply第一個參數制定該函數內部的this。 當傳遞函數對應的時候,第一個參數不可為空,必須為函數名稱。11,Curry化
<script>//curry化的add函數function add(x, y){var oldx = x, oldy = y;if(typeof oldy == "undefined"){return function(newy){console.log(oldx + newy);};} console.log(x + y);} console.log(typeof add(5));//functionadd(3)(4);//7 var add2000 = add(2000);add2000(10);//2010 </script>