摘要:對(duì)象被傳遞到從句中被捕獲。一些語言提供了尾遞歸優(yōu)化。這意味著如果一個(gè)函數(shù)返回自身遞歸調(diào)用的結(jié)果,那么調(diào)用的過程會(huì)被替換為一個(gè)循環(huán),可以顯著提高速度。構(gòu)建一個(gè)帶尾遞歸的函數(shù)。語言精粹讀書筆記函數(shù)
第四章 函數(shù) Functions (二) 參數(shù) arguments
arguments數(shù)組: 函數(shù)可以通過此參數(shù)訪問所有它被調(diào)用時(shí)傳遞給它的參數(shù)列表,包括哪些沒有被分配給函數(shù)聲明時(shí)定義的形式參數(shù)的多余參數(shù)。
類似數(shù)組"(array-like)"的對(duì)象。arguments擁有一個(gè)length屬性,沒有任何數(shù)組方法。
返回 returnreturn被執(zhí)行,函數(shù)立刻返回而不再執(zhí)行余下的語句
一個(gè)函數(shù)總是會(huì)返回一個(gè)值,沒有指定返回值,則返回 undefined
使用 new 調(diào)用函數(shù),且返回值不是一個(gè)對(duì)象,則返回this (該新對(duì)象)
異常 Exceptions異常是干擾程序的正常流程的不尋常(但并非完全是出乎意料的)事故
try { if(false) { throw { name:"TypeError", message:"number is required" } } }catch(e) { document.write(e.name + ": "+e.message) }
throw 語句中斷函數(shù)的運(yùn)行。對(duì)象被傳遞到catch 從句中被捕獲。
擴(kuò)充類型的功能通過給Function.prototype 增加方法,來使得該方法對(duì)所有函數(shù)可用:
Function.prototype.method = function(name,func) { this.prototype[name] = func; return this; }
這樣在函數(shù),數(shù)組,字符串,數(shù)字,正則表達(dá)式和布爾值等基本類型的構(gòu)造函數(shù)上添加方法時(shí),就可以省去prototype 這幾個(gè)字符。使得對(duì)應(yīng)的所有變量都適用改方法
為Number類型加上一個(gè)取整方法
Number.method("integer",function(){ return Math[this<0?"ceil":"floor"](this); });
為String加上一個(gè)去除首尾空白的方法
String.method("trim",function(){ return this.replace(/^s+|s+$/g,""); })
與類庫一起混用是,在確定沒有該方法時(shí)才添加它
// 符合條件時(shí)才增加方法 Function.prototype.method = function(name,func) { if(!this.prototype[name]) { this.prototype[name] = func; } return this; }遞歸
直接或者間接地調(diào)用自身的一種函數(shù),它把一個(gè)問題分解為一組相似的子問題
經(jīng)典的遞歸問題漢諾塔。塔上有3根柱子(1,2,3)和一套子直徑各不相同的空心圓盤。
開始盤子從小到大的順序堆疊在1號(hào)柱子上,目標(biāo)是要經(jīng)過2號(hào)柱子全部移動(dòng)到3號(hào)柱子上,中間不允許較大的盤放在較小的盤上;
分解成子問題:
將1號(hào)柱子上的從上到下的n-1個(gè)盤利用3號(hào)柱子移動(dòng)到2號(hào)柱子上。
將1號(hào)柱子上最下面的一個(gè)盤,直接移動(dòng)到3號(hào)柱子上.
最后把2號(hào)柱子上n-1個(gè)盤利用遞歸調(diào)用方法,全部移動(dòng)到3號(hào)柱子上。
var hanoi = function(disc,src,aux,dst) { if(disc > 0) { hanoi(disc -1,src,dst,aux); document.writeln("Move disc "+disc + " from "+src+"to "+dst); hanoi(disc-1,aux,src,dst) } }; hanoi(3,"Src","Aux","Dst"); // Move disc 1 from Srcto Dst Move disc 2 from Srcto Aux Move disc 1 from Dstto Aux Move disc 3 from Srcto Dst Move disc 1 from Auxto Src Move disc 2 from Auxto Dst Move disc 1 from Srcto Dst
利用遞歸高效地操作樹形結(jié)構(gòu),比如瀏覽器端的文檔對(duì)象模型(DOM),
var walk_the_DOM = function walk(node,func) { func(node); node = node.firstChild; while(node) { walk(node,func); node = node.nextSibling; } } // 定義 getElementsByAttribute 函數(shù), //它以一個(gè)屬性名稱字符串和一個(gè)可選的匹配值作為參數(shù)。 var getElementsByAttribute = function(att,value) { var results = []; walk_the_DOM(document.body,function(node) { var actual = node.nodeType === 1 $$ node.getAttribute(att); if(typeof actual === "string" && (actual === value || typeof value != "string")) { results.push(node) } }); return results; }
一些語言提供了尾遞歸優(yōu)化。這意味著如果一個(gè)函數(shù)返回自身遞歸調(diào)用的結(jié)果,那么調(diào)用的過程會(huì)被替換為一個(gè)循環(huán),可以顯著提高速度。
//構(gòu)建一個(gè)帶尾遞歸的函數(shù)。因?yàn)樗鼤?huì)返回自身調(diào)用的結(jié)果 // 實(shí)現(xiàn) factorial = n*(n-1)(n-2)... 1; var factorial = function factorial(i,a) { a = a || 1; if(i<2) { return a; } return factorial(i-1,a*i); }; document.writeln(factorial(4)) // 4*3*2*1 = 24作用域
作用域控制著變量與參數(shù)的可見性及生命周期
函數(shù)作用域: 定義在函數(shù)中的參數(shù)和變量在函數(shù)外部是不可見的,而在一個(gè)函數(shù)內(nèi)部任何位置定義的變量,在該函數(shù)內(nèi)部任何地方都可見。
在JavaScript中缺少會(huì)計(jì)作用域,最好的做法是在函數(shù)體的頂部聲明函數(shù)中可能用到的所有變量。
閉包 Closure閉包:函數(shù)可以訪問它被創(chuàng)建時(shí)所處的上下文環(huán)境。內(nèi)部函數(shù)可以訪問外部函數(shù)的實(shí)際變量而無需復(fù)制
作用域的好處是內(nèi)部函數(shù)可以訪問定義它們的外部函數(shù)的參數(shù)和變量(除了this 和arguments)
內(nèi)部函數(shù)擁有比它的外部函數(shù)更長(zhǎng)的生命周期。
var myObject = (function(){ var value = 0; return { increment:function(inc) { value += typeof inc === "number" ?inc :1; }, getValue:function() { return value; } } })()
上面定義的value變量對(duì)increment和getValue方法總是可用的,但函數(shù)的作用域使得它對(duì)其他的程序來說是不可見的
回調(diào) Callbacks異步請(qǐng)求,提供一個(gè)服務(wù)器的響應(yīng)到達(dá)是隨即觸發(fā)的回調(diào)函數(shù),模塊 Module
異步函數(shù)立即返回。
使用 函數(shù) 和 閉包創(chuàng)造模塊
模板的一般形式:
一個(gè)定義了私有變量和函數(shù)的函數(shù)
利用閉包創(chuàng)建可以訪問私有變量和函數(shù)的特權(quán)函數(shù)
返回這個(gè)特權(quán)函數(shù),或者把它們保存到一個(gè)可訪問到的地方。
利用前面使用的method方法,為String 增加一個(gè)deentityify 方法,尋找字符串中的HTML字符實(shí)體并把它們替換為對(duì)應(yīng)的字符。
String.method("deentityify",function(){ // 字符實(shí)體表,它映射字符實(shí)體的名字到對(duì)應(yīng)的字符 var entity = { quot: """, lt:"<", gt:">" }; // 返回 deetityify 方法 return function() { // 下面就是deetityify方法, return this.replace(/&([^&;]+);/g, function(a,b){ var r = entity[b]; return typeof r === "string"?r:a; } ) } }());
最后,使用()運(yùn)算符立刻調(diào)用我們剛剛構(gòu)造出來的函數(shù),這個(gè)調(diào)用所創(chuàng)建并返回的函數(shù)才是deentityify方法
document.writeln("<">".deentityify()) // <">級(jí)聯(lián)
讓執(zhí)行后的函數(shù)返回this 而不是 undefined,就可以啟用級(jí)聯(lián)
一個(gè)級(jí)聯(lián)中就,我們可以在多帶帶一條語句中依次調(diào)用同一個(gè)對(duì)象的很多方法。一個(gè)啟用了Ajax類庫可能允許我們以這樣的形式去編碼
getElement("myBoxDiv") .move(300,150) .width(100) .height(200) ... .tip("This box is resizeable")
上面的例子中,每次調(diào)用返回的結(jié)果都會(huì)被下一次調(diào)用所用。
柯里化柯里化允許我們把函數(shù)與傳遞給它的參數(shù)相結(jié)合,產(chǎn)生一個(gè)新的函數(shù)
Function.method("curry",function(){ var slice = Array.prototype.slice, args = slice.apply(arguments), that = this; return function() { return that.apply(null,args.concat(slice.apply(arguments))) } }) function add (a,b) {return a+b} add.curry(1)(6) //7記憶
函數(shù)可以將先前操作的結(jié)果記錄在某個(gè)對(duì)象里,從而避免無謂的重復(fù)運(yùn)算,這種優(yōu)化被稱為記憶
以Fibonacci數(shù)列為例,一個(gè)Fibonacci數(shù)字是之前兩個(gè)Fibonacci數(shù)字之和。最前面的兩個(gè)數(shù)字時(shí)0和1
var fibonacci = function (n) { return n<2? n:fibonacci(n-1) + fibonacci(n-2) } for(var i =0 ;i< = 10;i+=1) { document.writeln("http://"+i+": "+fibonacci(i)) } //0: 0 //1: 1 //2: 1 //3: 2 //4: 3 //5: 5 //6: 8 //7: 13 //8: 21 //9: 34 //10: 55
改進(jìn),利用memo數(shù)組保存我們的存儲(chǔ)結(jié)果,存儲(chǔ)結(jié)果可以隱藏在閉包中。
var fibonacci = function() { var memo = [0,1]; var fib = function(n) { var result = memo[n]; // 檢查結(jié)果是否已存在,如果已經(jīng)存在,就立刻返回這個(gè)結(jié)果 if(typeof result !== "number") { result = fib(n-1) + fib(n-2); memo[n]= result; } return result }; return fib; }(); fibonacci(10) //55
推而廣之,編寫一個(gè)函數(shù)來幫助我們構(gòu)造帶記憶功能的函數(shù)。
var memoizer = function(memo,formula) { var recur = function(n) { var result = memo[n]; if(typeof result !== "number") { result = formula(recur,n); memo[n] = result; } return result; }; return recur; } var fibonacci = memoizer([0,1],function(recur,n) { return recur(n-1) + recur(n-2); }); fibonacci(10) // 55
《JavaScript 語言精粹》讀書筆記 - 函數(shù)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93238.html
摘要:語言精粹讀書筆記第四章函數(shù)函數(shù)字面量函數(shù)字面量包含個(gè)部分第一部分,保留字第二部分,函數(shù)名,它可以被忽略。這個(gè)超級(jí)延遲綁定使得函數(shù)對(duì)高度復(fù)用。構(gòu)造器調(diào)用模式一個(gè)函數(shù),如果創(chuàng)建的目的就是希望結(jié)合的前綴來調(diào)用,那它就被稱為構(gòu)造器構(gòu)造。 《JavaScript 語言精粹》 讀書筆記 第四章 函數(shù) Functions 函數(shù)字面量 函數(shù)字面量包含4個(gè)部分: 第一部分, 保留字 function...
摘要:使用構(gòu)造器有個(gè)嚴(yán)重的危害,如果在調(diào)用構(gòu)造器函數(shù)的時(shí)候忘記使用前綴,不僅不會(huì)綁定到新對(duì)象,還會(huì)污染全局變量原型模式原型模式中,我們采用對(duì)象來繼承。 構(gòu)造器調(diào)用模式 當(dāng)一個(gè)函數(shù)對(duì)象被創(chuàng)建時(shí),F(xiàn)unction構(gòu)造器會(huì)運(yùn)行類似這樣的代碼: this.prototype = {constructor: this} new一個(gè)函數(shù)事會(huì)發(fā)生: Function.method(new, functio...
摘要:于是我就先把這本薄的經(jīng)典書語言精粹修訂版豆瓣讀書本書簡(jiǎn)介總共章,除去附錄,才頁,讀完并記錄了一些筆記。讀書筆記還可以分享給別人看。編程語言第版定義了的標(biāo)準(zhǔn)。程序檢查時(shí)丟棄值為函數(shù)的屬性。 之前看到這篇文章,前端網(wǎng)老姚淺談:怎么學(xué)JavaScript?,說到怎么學(xué)習(xí)JavaScript,那就是看書、分析源碼。10本書讀2遍的好處,應(yīng)該大于一本書讀20遍??磿鲃?dòng)學(xué)習(xí),看視頻是被動(dòng)學(xué)習(xí)。看...
摘要:第條盡量少使用全局對(duì)象避免聲明全局變量盡量聲明局部變量避免對(duì)全局變量增加屬性第條始終聲明局部變量第條避免使用語句第條熟練使用閉包的函數(shù)值包含了比調(diào)用他們時(shí)執(zhí)行所需要的代碼還要更多的信息。那些在其所涵蓋的作用域內(nèi)跟蹤變量的函數(shù)稱為閉包。 書還沒看完。一遍看,一遍寫讀書筆記。 這本書的序是JavaScript之父Brendan Eich寫的,作者是JavaScript標(biāo)準(zhǔn)化委員會(huì)專家。可想...
摘要:前言由于最近的項(xiàng)目用到了一些的代碼,所以我?guī)е闷嫘模J(rèn)真閱讀了這本書,粗略地了解語言的基本結(jié)構(gòu)和特性,對(duì)于一些不熟悉的新概念,以記錄的形式加強(qiáng)印象,也是對(duì)學(xué)習(xí)的反思總結(jié)。 前言 由于最近的項(xiàng)目用到了一些js的代碼,所以我?guī)е闷嫘?,認(rèn)真閱讀了這本書,粗略地了解js語言的基本結(jié)構(gòu)和特性,對(duì)于一些不熟悉的新概念,以記錄的形式加強(qiáng)印象,也是對(duì)學(xué)習(xí)的反思總結(jié)。 一、字面量(literals...
閱讀 3101·2021-11-24 11:14
閱讀 3570·2021-11-22 15:22
閱讀 3236·2021-09-27 13:36
閱讀 756·2021-08-31 14:29
閱讀 1354·2019-08-30 15:55
閱讀 1813·2019-08-29 17:29
閱讀 1168·2019-08-29 16:24
閱讀 2463·2019-08-26 13:48