欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript中的高級函數

 更新時間:2018年01月04日 09:31:21   作者:Claiyre  
在JavaScript中,函數的功能十分強大,除了函數相關的基礎知識外,掌握一些高級函數并應用起來,不僅能讓JS代碼看起來更為精簡,還可以提升性能,本文是小編總結的一些常用的、重要的函數

在JavaScript中,函數的功能十分強大。它們是第一類對象,也可以作為另一個對象的方法,還可以作為參數傳入另一個函數,不僅如此,還能被一個函數返回!可以說,在JS中,函數無處不在,無所不能,堪比孫猴子呀!當你運用好函數時,它能助你取西經,讓代碼變得優(yōu)雅簡潔,運用不好時,那就遭殃了,要大鬧天宮咯~

除了函數相關的基礎知識外,掌握一些高級函數并應用起來,不僅能讓JS代碼看起來更為精簡,還可以提升性能。以下是小編總結的一些常用的、重要的高級函數,加上了一些個人見解,特此記錄下來。如果您是JS初學者,也不要被“高級”兩個字嚇到,因為文中穿插講解了一些原型、this等基礎知識,相信并不難理解。如果您是JS大牛,也可以把本文用來查漏補缺。

正文

作用域安全的構造函數

function Person(name,age){
 this.name = name;
 this.age = age;
}
var p1 = new Person("Claiyre",80);

相信您對上面的構造函數一定不陌生,但是,,如果某個粗心的程序猿調用這個構造函數時忘記加 new 了會發(fā)生什么?

var p3 = Person("Tom",30);
console.log(p3);    //undefined
console.log(window.name);  //Tom

由于使用了不安全的構造函數,上面的代碼意外的改變了window的name,因為 this 對象是在運行時綁定的,使用new調用構造函數時 this 是指向新創(chuàng)建的對象的,不使用 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);
 } 
}

這樣就避免了在全局對象上意外更改或設置屬性。

實現這個安全模式,相當于鎖定了調用構造函數的環(huán)境,因此借用構造函數繼承模式可能會出現問題,解決方法是組合使用原型鏈和構造函數模式,即組合繼承。

如果您是一個JS庫或框架的開發(fā)者,相信作用域安全的構造函數一定對您非常有用。在多人協作的項目中,為了避免他們誤改了全局對象,也應使用作用域安全的構造函數。

惰性載入函數

由于瀏覽器間的行為差異,代碼中可能會有許多檢測瀏覽器行為的if語句。但用戶的瀏覽器若支持某一特性,便會一直支持,所以這些if語句,只用被執(zhí)行一次,即便只有一個if語句的代碼,也比沒有要快。

惰性載入表示函數執(zhí)行的分支僅會執(zhí)行一次,有兩種實現惰性載入的方式,第一種就是在函數第一次被調用時再處理函數,用檢測到的結果重寫原函數。

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(){
 //用其他解決方案
 }
 } 
})();

惰性載入函數的有點是在只初次執(zhí)行時犧牲一點性能,之后便不會再有多余的消耗性能。

函數綁定作用域

在JS中,函數的作用域是在函數被調用時動態(tài)綁定的,也就是說函數的this對象的指向是不定的,但在一些情況下,我們需要讓某一函數的執(zhí)行作用域固定,總是指向某一對象。這時怎么辦呢?

當當當~~可以用函數綁定作用域函數呀

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的概念很簡單:只傳遞部分參數來調用函數,然后讓函數返回另一個函數去處理剩下的參數??梢岳斫鉃橘x予了函數“加載”的能力。

許多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函數,又稱“去抖函數”。它的功能也很簡單直接,就是防止某一函數被連續(xù)調用,從而導致瀏覽器卡死或崩潰。用法如下:

var myFunc = debounce(function(){
 //繁重、耗性能的操作
},250);
window.addEventListener('resize',myFunc);

像窗口的resize,這類可以以較高的速率觸發(fā)的事件,非常適合用去抖函數,這時也可稱作“函數節(jié)流”,避免給瀏覽器帶來過大的性能負擔。

具體的實現時,當函數被調用時,不立即執(zhí)行相應的語句,而是等待固定的時間w,若在w時間內,即等待還未結束時,函數又被調用了一次,則再等待w時間,重復上述過程,直到最后一次被調用后的w時間內該函數都沒有被再調用,則執(zhí)行相應的代碼。

實現代碼如下:

function debounce(fn,wait){
 var td;
 return function(){
 clearTimeout(td);
 td= setTimeout(fn,wait);
 }
}

once函數

顧名思義,once函數是僅僅會被執(zhí)行一次的函數。具體實現如下:

function once(fn){
 var result;
 return function(){
 if(fn){
 result = fn(arguments);
 fn = null;
 }
 return result;
 }
}
var init = once(function(){
 //初始化操作
})

在被執(zhí)行過一次后,參數fn就被賦值null了,那么在接下來被調用時,便再也不會進入到if語句中了,也就是第一次被調用后,該函數永遠不會被執(zhí)行了。

還可以對上述once函數進行改進,不僅可以傳入函數,同時還可以給傳入的函數綁定作用域u,同時實現了bind和once。

function once(fn,context){
 var result;
 return function(){
 if(fn){
 result = fn.apply(context,arguments);
 fn = null;
 }
 return result;
 }
}

結語

通過以上的閱讀,不難發(fā)現很多“高級函數”的實現其實并不復雜,數十行代碼便可搞定,但重要的是能真正理解它們的原理,在實際中適時地應用,以此性能提升,讓代碼簡潔,邏輯清晰

相關文章

  • bootstrap Table的一些小操作

    bootstrap Table的一些小操作

    這篇文章主要為大家詳細介紹了bootstrap Table的一些小操作,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • JS中使用new Option()實現時間聯動效果

    JS中使用new Option()實現時間聯動效果

    這篇文章主要介紹了JS中使用new Option()實現時間聯動效果,需要的朋友可以參考下
    2018-12-12
  • 記一次webpack3升級webpack4的踩坑經歷

    記一次webpack3升級webpack4的踩坑經歷

    這篇文章主要介紹了記一次webpack3升級webpack4的踩坑經歷,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • JavaScript正則表達式函數總結(常用)

    JavaScript正則表達式函數總結(常用)

    正則表達式作為一種匹配處理字符串的利器在很多語言中都得到了廣泛實現和應用.這篇文章主要介紹了JavaScript正則表達式函數總結,需要的朋友可以參考下
    2018-02-02
  • 詳解JavaScript事件循環(huán)

    詳解JavaScript事件循環(huán)

    JavaScript事件循環(huán)是一種機制,用于處理異步事件和回調函數。它是JavaScript運行時環(huán)境的一部分,負責管理事件隊列和調用棧。文章中有詳細的代碼示例,需要的朋友可以參考一下
    2023-04-04
  • webpack公共組件引用路徑簡化小技巧

    webpack公共組件引用路徑簡化小技巧

    日常開發(fā)中,我們會常常把一些功能提取出來,包裝成一個公共模塊或者組件.這篇文章主要介紹了webpack公共組件引用路徑簡化小技巧,非常具有實用價值,需要的朋友可以參考下
    2018-06-06
  • JavaScript中正則表達式的實際應用詳解

    JavaScript中正則表達式的實際應用詳解

    這篇文章主要給大家介紹了關于JavaScript中正則表達式實際應用的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-05-05
  • ES6 fetch函數與后臺交互實現

    ES6 fetch函數與后臺交互實現

    最近在學習react-native,遇到調用后端接口的問題??戳丝垂俜轿臋n,推薦使用es6的fetch來與后端進行交互,這篇文章主要介紹了ES6 fetch函數與后臺交互實現,感興趣的小伙伴們可以參考一下
    2018-11-11
  • 在javascript中實現函數數組的方法

    在javascript中實現函數數組的方法

    js不進行類型檢查,數組可以存放任何東西。于是我就想數組里可否存放函數呢,下面就為大家詳細介紹下
    2013-12-12
  • 超贊的動手創(chuàng)建JavaScript框架的詳細教程

    超贊的動手創(chuàng)建JavaScript框架的詳細教程

    這篇文章主要介紹了動手創(chuàng)建JavaScript框架的詳細教程,包括DOM和各種屬性的調試等各個方面,超級推薦!需要的朋友可以參考下
    2015-06-06

最新評論