在JavaScript中高階函數的使用方法
在JavaScript中,函數的功能十分強大,除了函數相關的基礎知識外,掌握一些高階函數並應用起來,不僅能讓JS程式碼看起來更為精簡,還可以提升效能,本文是小編總結的一些常用的、重要的函數
在JavaScript中,函數的功能十分強大。它們是第一類對象,也可以作為另一個對象的方法,還可以作為參數傳入另一個函數,不僅如此,還能被一個函數返回!可以說,在JS中,函數無所不在,無所不能,堪比孫猴子呀!當你運用好函數時,它能助你取西經,讓程式碼變得優雅簡潔,運用不好時,那就遭殃了,要大鬧天宮咯~
除了函數相關的基礎知識外,掌握一些高階函數並應用起來,不僅能讓JS程式碼看起來更為精簡,還可以提升效能。以下是小編總結的一些常用的、重要的高階函數,加上了一些個人見解,特此記錄下來。如果您是JS初學者,也不要被「高級」兩個字嚇到,因為文中穿插講解了一些原型、this等基礎知識,相信並不難理解。如果您是JS大牛,也可以把本文用來查漏補缺。
正文
作用域安全的建構子
function Person(name,age){ this.name = name; this.age = age; } var p1 = new Person("Claiyre",80);
相信您對上面的構造函數一定不陌生,但是,,如果某個粗心的程式猿呼叫這個建構函式時忘記加new 了會發生什麼事?
var p3 = Person("Tom",30); console.log(p3); //undefined console.log(window.name); //Tom
由於使用了不安全的建構函數,上面的程式碼意外的改變了window的name,因為this 物件是在執行時間綁定的,使用new呼叫建構函數時this 是指向新建立的物件的,不使用new 時, this 是指向window的。
由於window的name屬性是用來識別連結目標和frame的,所在這裡對該屬性的偶然覆蓋可能導致其他錯誤。
作用域安全的建構子會先確認this 物件是正確類型的實例,然後再進行更改,如下:
function Person(name,age){ if(this instanceof Person){ this.name = name; this.age = age; } else { return new Person(name,age); } }
這樣就避免了在全域物件上意外更改或設定屬性。
實作這個安全模式,相當於鎖定了呼叫建構函式的環境,因此借用建構函式繼承模式可能會出現問題,解決方法是組合使用原型鍊和建構函式模式,也就是組合繼承。
如果您是一個JS函式庫或框架的開發者,相信作用域安全的建構子一定對您非常有用。在多人協作的專案中,為了避免他們誤改了全域對象,也應使用作用域安全的建構子。
惰性載入函數
由於瀏覽器間的行為差異,程式碼中可能會有許多偵測瀏覽器行為的if語句。但使用者的瀏覽器若支援某一特性,便會一直支持,所以這些if語句,只用被執行一次,即便只有一個if語句的程式碼,也比沒有要快。
惰性載入表示函數執行的分支只會執行一次,有兩種實現惰性載入的方式,第一種就是在函數第一次被呼叫時再處理函數,用偵測到的結果重寫原函數。
function detection(){ if(//支持某特性){ detection = function(){ //直接用支持的特性 } } else if(//支持第二种特性){ detection = function(){ //用第二种特性 } } else { detection = function(){ //用其他解决方案 } } }
第二種實作惰性載入的方式是在宣告函數時就指定適當的函數
var detection = (function(){ if(//支持某特性){ return function(){ //直接用支持的特性 } } else if(//支持第二种特性){ return function(){ //用第二种特性 } } else { return function(){ //用其他解决方案 } } })();
惰性載入函數的有點是在只初次執行時犧牲一點效能,之後便不會再有多餘的消耗性能。
函數綁定作用域
在JS中,函數的作用域是在函數被呼叫時動態綁定的,也就是說函數的this物件的指向是不定的,但在某些情況下,我們需要讓某一函數的執行作用域固定,總是指向某一物件。這時怎麼辦呢?
噹噹~~可以用函數綁定作用域函數呀
function bind(fn,context){ return function(){ return fn.apply(context,arguments); } }
用法:
var person1 = { name: "claiyre", sayName: function(){ alert(this.name); } } var sayPerson1Name = bind(person1.sayName,person1); sayPerson1Name(); //claiyre
call 函數和apply 函數可以暫時改變函數的作用域,使用bind函數可以得到一個綁定了作用域的函數
函數柯里化(curry)
curry的概念很簡單:只傳遞部分參數來呼叫函數,然後讓函數傳回另一個函數去處理剩下的參數。可以理解為賦予了函數“加載”的能力。
許多js函式庫中都封裝了curry函數,具體使用可以這樣。
var match = curry(function(what,str){ return str.match(what) }); var hasNumber = match(/[0-9]+/g); var hasSpace = match(/\s+/g) hasNumber("123asd"); //['123'] hasNumber("hello world!"); //null hasSpace("hello world!"); //[' ']; hasSpace("hello"); //null console.log(match(/\s+/g,'i am Claiyre')); //直接全部传参也可: [' ',' ']
一旦函數經過柯里化,我們就可以先傳遞部分參數呼叫它,然後得到一個更具體的函數。這個更具體的函數透過閉包幫我們記住了第一次傳遞的參數,最後我們就可以用這個更具體的函數為所欲為啦~
一個較為簡單的實作curry的方式:
function curry(fn){ var i = 0; var outer = Array.prototype.slice.call(arguments,1); var len = fn.length; return function(){ var inner = outer.concat(Array.prototype.slice.call(arguments)); return inner.length === len?fn.apply(null,inner):function (){ var finalArgs = inner.concat(Array.prototype.slice.call(arguments)); return fn.apply(null,finalArgs); } } }
debounce函數
debounce函數,又稱為「去抖動函數」。它的功能也很簡單直接,就是防止某一函數被連續調用,導致瀏覽器卡死或崩潰。用法如下:
var myFunc = debounce(function(){ //繁重、耗性能的操作 },250); window.addEventListener('resize',myFunc);
像窗口的resize,这类可以以较高的速率触发的事件,非常适合用去抖函数,这时也可称作“函数节流”,避免给浏览器带来过大的性能负担。
具体的实现时,当函数被调用时,不立即执行相应的语句,而是等待固定的时间w,若在w时间内,即等待还未结束时,函数又被调用了一次,则再等待w时间,重复上述过程,直到最后一次被调用后的w时间内该函数都没有被再调用,则执行相应的代码。
实现代码如下:
function debounce(fn,wait){ var td; return function(){ clearTimeout(td); td= setTimeout(fn,wait); } }
once函数
顾名思义,once函数是仅仅会被执行一次的函数。具体实现如下:
function once(fn){ var result; return function(){ if(fn){ result = fn(arguments); fn = null; } return result; } } var init = once(function(){ //初始化操作 })
在被执行过一次后,参数fn就被赋值null了,那么在接下来被调用时,便再也不会进入到if语句中了,也就是第一次被调用后,该函数永远不会被执行了。
还可以对上述once函数进行改进,不仅可以传入函数,同时还可以给传入的函数绑定作用域u,同时实现了bind和once。
function once(fn,context){ var result; return function(){ if(fn){ result = fn.apply(context,arguments); fn = null; } return result; } }
上面是我整理给大家的,希望今后会对大家有帮助。
相关文章:
以上是在JavaScript中高階函數的使用方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Go語言提供了兩種動態函數創建技術:closures和反射。 closures允許存取閉包作用域內的變量,而反射可使用FuncOf函數建立新函數。這些技術在自訂HTTP路由器、實現高度可自訂的系統和建置可插拔的元件方面非常有用。

在C++函數命名中,考慮參數順序至關重要,可提高可讀性、減少錯誤並促進重構。常見的參數順序約定包括:動作-物件、物件-動作、語意意義和遵循標準函式庫。最佳順序取決於函數目的、參數類型、潛在混淆和語言慣例。

1. SUM函數,用於對一列或一組單元格中的數字進行求和,例如:=SUM(A1:J10)。 2、AVERAGE函數,用於計算一列或一組儲存格中的數字的平均值,例如:=AVERAGE(A1:A10)。 3.COUNT函數,用於計算一列或一組單元格中的數字或文字的數量,例如:=COUNT(A1:A10)4、IF函數,用於根據指定的條件進行邏輯判斷,並返回相應的結果。

C++函數中預設參數的優點包括簡化呼叫、增強可讀性、避免錯誤。缺點是限制靈活性、命名限制。可變參數的優點包括無限彈性、動態綁定。缺點包括複雜性更高、隱式型別轉換、除錯困難。

C++中的函數傳回參考類型的好處包括:效能提升:引用傳遞避免了物件複製,從而節省了記憶體和時間。直接修改:呼叫方可以直接修改傳回的參考對象,而無需重新賦值。程式碼簡潔:引用傳遞簡化了程式碼,無需額外的賦值操作。

自訂PHP函數與預定義函數的差異在於:作用域:自訂函數僅限於其定義範圍,而預定義函數可在整個腳本中存取。定義方式:自訂函數使用function關鍵字定義,而預先定義函數則由PHP核心定義。參數傳遞:自訂函數接收參數,而預先定義函數可能不需要參數。擴充性:自訂函數可以根據需要創建,而預定義函數是內建的且無法修改。

C++中的異常處理可透過自訂異常類別增強,提供特定錯誤訊息、上下文資訊以及根據錯誤類型執行自訂操作。定義繼承自std::exception的異常類,提供特定的錯誤訊息。使用throw關鍵字拋出自訂異常。在try-catch區塊中使用dynamic_cast將捕獲到的異常轉換為自訂異常類型。在實戰案例中,open_file函數會拋出FileNotFoundException異常,捕捉並處理該異常可提供更具體的錯誤訊息。
