最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript中的高級(jí)函數(shù)

 更新時(shí)間:2018年01月04日 09:31:21   作者:Claiyre  
在JavaScript中,函數(shù)的功能十分強(qiáng)大,除了函數(shù)相關(guān)的基礎(chǔ)知識(shí)外,掌握一些高級(jí)函數(shù)并應(yīng)用起來(lái),不僅能讓JS代碼看起來(lái)更為精簡(jiǎn),還可以提升性能,本文是小編總結(jié)的一些常用的、重要的函數(shù)

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

除了函數(shù)相關(guān)的基礎(chǔ)知識(shí)外,掌握一些高級(jí)函數(shù)并應(yīng)用起來(lái),不僅能讓JS代碼看起來(lái)更為精簡(jiǎn),還可以提升性能。以下是小編總結(jié)的一些常用的、重要的高級(jí)函數(shù),加上了一些個(gè)人見(jiàn)解,特此記錄下來(lái)。如果您是JS初學(xué)者,也不要被“高級(jí)”兩個(gè)字嚇到,因?yàn)槲闹写┎逯v解了一些原型、this等基礎(chǔ)知識(shí),相信并不難理解。如果您是JS大牛,也可以把本文用來(lái)查漏補(bǔ)缺。

正文

作用域安全的構(gòu)造函數(shù)

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

相信您對(duì)上面的構(gòu)造函數(shù)一定不陌生,但是,,如果某個(gè)粗心的程序猿調(diào)用這個(gè)構(gòu)造函數(shù)時(shí)忘記加 new 了會(huì)發(fā)生什么?

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

由于使用了不安全的構(gòu)造函數(shù),上面的代碼意外的改變了window的name,因?yàn)?this 對(duì)象是在運(yùn)行時(shí)綁定的,使用new調(diào)用構(gòu)造函數(shù)時(shí) this 是指向新創(chuàng)建的對(duì)象的,不使用 new 時(shí), this 是指向window的。

由于window的name屬性是用來(lái)識(shí)別鏈接目標(biāo)和frame的,所在這里對(duì)該屬性的偶然覆蓋可能導(dǎo)致其他錯(cuò)誤。

作用域安全的構(gòu)造函數(shù)會(huì)首先確認(rèn) this 對(duì)象是正確類(lèi)型的實(shí)例,然后再進(jìn)行更改,如下:

function Person(name,age){
 if(this instanceof Person){
 this.name = name;
 this.age = age;
 } else {
 return new Person(name,age);
 } 
}

這樣就避免了在全局對(duì)象上意外更改或設(shè)置屬性。

實(shí)現(xiàn)這個(gè)安全模式,相當(dāng)于鎖定了調(diào)用構(gòu)造函數(shù)的環(huán)境,因此借用構(gòu)造函數(shù)繼承模式可能會(huì)出現(xiàn)問(wèn)題,解決方法是組合使用原型鏈和構(gòu)造函數(shù)模式,即組合繼承。

如果您是一個(gè)JS庫(kù)或框架的開(kāi)發(fā)者,相信作用域安全的構(gòu)造函數(shù)一定對(duì)您非常有用。在多人協(xié)作的項(xiàng)目中,為了避免他們誤改了全局對(duì)象,也應(yīng)使用作用域安全的構(gòu)造函數(shù)。

惰性載入函數(shù)

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

惰性載入表示函數(shù)執(zhí)行的分支僅會(huì)執(zhí)行一次,有兩種實(shí)現(xiàn)惰性載入的方式,第一種就是在函數(shù)第一次被調(diào)用時(shí)再處理函數(shù),用檢測(cè)到的結(jié)果重寫(xiě)原函數(shù)。

function detection(){
 if(//支持某特性){
 detection = function(){
 //直接用支持的特性
 }
 } else if(//支持第二種特性){
 detection = function(){
 //用第二種特性
 }
 } else {
 detection = function(){
 //用其他解決方案
 }
 }
}

第二種實(shí)現(xiàn)惰性載入的方式是在聲明函數(shù)時(shí)就指定適當(dāng)?shù)暮瘮?shù)

var detection = (function(){
 if(//支持某特性){
 return function(){
 //直接用支持的特性
 }
 } else if(//支持第二種特性){
 return function(){
 //用第二種特性
 }
 } else {
 return function(){
 //用其他解決方案
 }
 } 
})();

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

函數(shù)綁定作用域

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

當(dāng)當(dāng)當(dāng)~~可以用函數(shù)綁定作用域函數(shù)呀

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 函數(shù)和 apply 函數(shù)可以臨時(shí)改變函數(shù)的作用域,使用bind函數(shù)可以得到一個(gè)綁定了作用域的函數(shù)

函數(shù)柯里化(curry)

curry的概念很簡(jiǎn)單:只傳遞部分參數(shù)來(lái)調(diào)用函數(shù),然后讓函數(shù)返回另一個(gè)函數(shù)去處理剩下的參數(shù)??梢岳斫鉃橘x予了函數(shù)“加載”的能力。

許多js庫(kù)中都封裝了curry函數(shù),具體使用可以這樣。

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')); //直接全部傳參也可: [' ',' ']

一旦函數(shù)經(jīng)過(guò)柯里化,我們就可以先傳遞部分參數(shù)調(diào)用它,然后得到一個(gè)更具體的函數(shù)。這個(gè)更具體的函數(shù)通過(guò)閉包幫我們記住了第一次傳遞的參數(shù),最后我們就可以用這個(gè)更具體的函數(shù)為所欲為啦~

一個(gè)較為簡(jiǎn)單的實(shí)現(xiàn)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函數(shù)

debounce函數(shù),又稱(chēng)“去抖函數(shù)”。它的功能也很簡(jiǎn)單直接,就是防止某一函數(shù)被連續(xù)調(diào)用,從而導(dǎo)致瀏覽器卡死或崩潰。用法如下:

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

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

具體的實(shí)現(xiàn)時(shí),當(dāng)函數(shù)被調(diào)用時(shí),不立即執(zhí)行相應(yīng)的語(yǔ)句,而是等待固定的時(shí)間w,若在w時(shí)間內(nèi),即等待還未結(jié)束時(shí),函數(shù)又被調(diào)用了一次,則再等待w時(shí)間,重復(fù)上述過(guò)程,直到最后一次被調(diào)用后的w時(shí)間內(nèi)該函數(shù)都沒(méi)有被再調(diào)用,則執(zhí)行相應(yīng)的代碼。

實(shí)現(xiàn)代碼如下:

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

once函數(shù)

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

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

在被執(zhí)行過(guò)一次后,參數(shù)fn就被賦值null了,那么在接下來(lái)被調(diào)用時(shí),便再也不會(huì)進(jìn)入到if語(yǔ)句中了,也就是第一次被調(diào)用后,該函數(shù)永遠(yuǎn)不會(huì)被執(zhí)行了。

還可以對(duì)上述once函數(shù)進(jìn)行改進(jìn),不僅可以傳入函數(shù),同時(shí)還可以給傳入的函數(shù)綁定作用域u,同時(shí)實(shí)現(xiàn)了bind和once。

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

結(jié)語(yǔ)

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

相關(guān)文章

  • Javascript中匿名函數(shù)的調(diào)用與寫(xiě)法實(shí)例詳解(多種)

    Javascript中匿名函數(shù)的調(diào)用與寫(xiě)法實(shí)例詳解(多種)

    js中定義函數(shù)的方式有很多種,函數(shù)直接量就是其中一種,下面通過(guò)本文給大家介紹匿名函數(shù)是如何調(diào)用的及匿名函數(shù)的n中寫(xiě)法,對(duì)js匿名函數(shù)調(diào)用,js匿名函數(shù)寫(xiě)法相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • JS中的模糊查詢(xún)功能

    JS中的模糊查詢(xún)功能

    這篇文章主要介紹了JS中的模糊查詢(xún)功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • JavaScript中的常見(jiàn)錯(cuò)誤與異常處理分析

    JavaScript中的常見(jiàn)錯(cuò)誤與異常處理分析

    這篇文章主要為大家信息介紹了JavaScript中的常見(jiàn)錯(cuò)誤與異常處理的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • js自調(diào)用匿名函數(shù)的三種寫(xiě)法(推薦)

    js自調(diào)用匿名函數(shù)的三種寫(xiě)法(推薦)

    下面小編就為大家?guī)?lái)一篇js自調(diào)用匿名函數(shù)的三種寫(xiě)法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-08-08
  • 微信小程序返回上一頁(yè)的各種方法實(shí)例

    微信小程序返回上一頁(yè)的各種方法實(shí)例

    在開(kāi)發(fā)小程序的時(shí)候我們總是能遇到各種奇怪的需求,下面這篇文章主要給大家介紹了關(guān)于微信小程序返回上一頁(yè)的各種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • drag-and-drop實(shí)現(xiàn)圖片瀏覽器預(yù)覽

    drag-and-drop實(shí)現(xiàn)圖片瀏覽器預(yù)覽

    chrome的drag and drop API,它能將本地的圖片放到瀏覽器中進(jìn)行預(yù)覽,猜想一下當(dāng)我們把圖片拖拽到瀏覽器里會(huì)發(fā)生什么事情,你的瀏覽器試圖打開(kāi)一個(gè)新的頁(yè)面并加載這個(gè)圖片。這篇文章給我們介紹drag-and-drop實(shí)現(xiàn)圖片瀏覽器預(yù)覽,需要的朋友可以參考下
    2015-08-08
  • js 獲取元素在頁(yè)面上的偏移量的方法匯總

    js 獲取元素在頁(yè)面上的偏移量的方法匯總

    javascript可以通過(guò)四個(gè)屬性可以獲得元素的偏移量,分別是1、offsetHeight,2、offsetWidth,3、offsetLeft,4、offsetTop,今天我們就來(lái)具體談一下獲取頁(yè)面元素偏移量的最佳方法。
    2015-04-04
  • window.parent調(diào)用父框架時(shí) ie跟火狐不兼容問(wèn)題

    window.parent調(diào)用父框架時(shí) ie跟火狐不兼容問(wèn)題

    window.parent調(diào)用父框架時(shí),ie跟火狐不兼容問(wèn)題!
    2009-07-07
  • JS實(shí)現(xiàn)動(dòng)態(tài)生成html table表格的方法分析

    JS實(shí)現(xiàn)動(dòng)態(tài)生成html table表格的方法分析

    這篇文章主要介紹了JS實(shí)現(xiàn)動(dòng)態(tài)生成html table表格的方法,結(jié)合實(shí)例形式分析了javascript針對(duì)數(shù)組數(shù)據(jù)的讀取、遍歷以及動(dòng)態(tài)生成相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • 詳解使用JWT實(shí)現(xiàn)單點(diǎn)登錄(完全跨域方案)

    詳解使用JWT實(shí)現(xiàn)單點(diǎn)登錄(完全跨域方案)

    這篇文章主要介紹了詳解使用JWT實(shí)現(xiàn)單點(diǎn)登錄(完全跨域方案),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08

最新評(píng)論

科技| 钟山县| 留坝县| 红原县| 武强县| 通州市| 十堰市| 南漳县| 全椒县| 诸城市| 洪湖市| 溧水县| 闻喜县| 巴林右旗| 阿拉善左旗| 陵水| 留坝县| 沙坪坝区| 新兴县| 武冈市| 丽水市| 铁力市| 漾濞| 应城市| 大同县| 长武县| 古丈县| 清原| 清镇市| 偃师市| 乌鲁木齐市| 东港市| 衡阳市| 安康市| 仁寿县| 奎屯市| 辽源市| 上杭县| 青海省| 永靖县| 白城市|