国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

談?wù)凧S中的高級函數(shù)

raoyi / 1578人閱讀

摘要:作用域安全的構(gòu)造函數(shù)會首先確認(rèn)對象是正確類型的實(shí)例,然后再進(jìn)行更改,如下這樣就避免了在全局對象上意外更改或設(shè)置屬性。在多人協(xié)作的項(xiàng)目中,為了避免他們誤改了全局對象,也應(yīng)使用作用域安全的構(gòu)造函數(shù)。

博客原文地址:Claiyre的個人博客
如需轉(zhuǎn)載,請?jiān)谖恼麻_頭注明原文地址

在JavaScript中,函數(shù)的功能十分強(qiáng)大。它們是第一類對象,也可以作為另一個對象的方法,還可以作為參數(shù)傳入另一個函數(shù),不僅如此,還能被一個函數(shù)返回!可以說,在JS中,函數(shù)無處不在,無所不能,堪比孫猴子呀!當(dāng)你運(yùn)用好函數(shù)時(shí),它能助你取西經(jīng),讓代碼變得優(yōu)雅簡潔,運(yùn)用不好時(shí),那就遭殃了,要大鬧天宮咯~
除了函數(shù)相關(guān)的基礎(chǔ)知識外,掌握一些高級函數(shù)并應(yīng)用起來,不僅能讓JS代碼看起來更為精簡,還可以提升性能。以下是博主總結(jié)的一些常用的、重要的高級函數(shù),加上了一些個人見解,特此記錄下來。如果您是JS初學(xué)者,也不要被“高級”兩個字嚇到,因?yàn)槲闹写┎逯v解了一些原型、this等基礎(chǔ)知識,相信并不難理解。如果您是JS大牛,也可以把本文用來查漏補(bǔ)缺。

正文 作用域安全的構(gòu)造函數(shù)
function Person(name,age){
    this.name = name;
    this.age = age;
}
var p1 = new Person("Claiyre",80);

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

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

由于使用了不安全的構(gòu)造函數(shù),上面的代碼意外的改變了window的name,因?yàn)?b>this對象是在運(yùn)行時(shí)綁定的,使用new調(diào)用構(gòu)造函數(shù)時(shí)this是指向新創(chuàng)建的對象的,不使用new時(shí),this是指向window的。
由于window的name屬性是用來識別鏈接目標(biāo)和frame的,所在這里對該屬性的偶然覆蓋可能導(dǎo)致其他錯誤。

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

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

這樣就避免了在全局對象上意外更改或設(shè)置屬性。
實(shí)現(xiàn)這個安全模式,相當(dāng)于鎖定了調(diào)用構(gòu)造函數(shù)的環(huán)境,因此借用構(gòu)造函數(shù)繼承模式可能會出現(xiàn)問題,解決方法是組合使用原型鏈和構(gòu)造函數(shù)模式,即組合繼承。
如果您是一個JS庫或框架的開發(fā)者,相信作用域安全的構(gòu)造函數(shù)一定對您非常有用。在多人協(xié)作的項(xiàng)目中,為了避免他們誤改了全局對象,也應(yīng)使用作用域安全的構(gòu)造函數(shù)。

惰性載入函數(shù)

由于瀏覽器間的行為差異,代碼中可能會有許多檢測瀏覽器行為的if語句。但用戶的瀏覽器若支持某一特性,便會一直支持,所以這些if語句,只用被執(zhí)行一次,即便只有一個if語句的代碼,也比沒有要快。
惰性載入表示函數(shù)執(zhí)行的分支僅會執(zhí)行一次,有兩種實(shí)現(xiàn)惰性載入的方式,第一種就是在函數(shù)第一次被調(diào)用時(shí)再處理函數(shù),用檢測到的結(jié)果重寫原函數(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)性能,之后便不會再有多余的消耗性能。

函數(shù)綁定作用域

在JS中,函數(shù)的作用域是在函數(shù)被調(diào)用時(shí)動態(tài)綁定的,也就是說函數(shù)的this對象的指向是不定的,但在一些情況下,我們需要讓某一函數(shù)的執(zhí)行作用域固定,總是指向某一對象。這時(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ù)可以得到一個綁定了作用域的函數(shù)

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

curry的概念很簡單:只傳遞部分參數(shù)來調(diào)用函數(shù),然后讓函數(shù)返回另一個函數(shù)去處理剩下的參數(shù)。可以理解為賦予了函數(shù)“加載”的能力。
許多js庫中都封裝了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)過柯里化,我們就可以先傳遞部分參數(shù)調(diào)用它,然后得到一個更具體的函數(shù)。這個更具體的函數(shù)通過閉包幫我們記住了第一次傳遞的參數(shù),最后我們就可以用這個更具體的函數(shù)為所欲為啦~

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

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

像窗口的resize,這類可以以較高的速率觸發(fā)的事件,非常適合用去抖函數(shù),這時(shí)也可稱作“函數(shù)節(jié)流”,避免給瀏覽器帶來過大的性能負(fù)擔(dān)。
具體的實(shí)現(xiàn)時(shí),當(dāng)函數(shù)被調(diào)用時(shí),不立即執(zhí)行相應(yīng)的語句,而是等待固定的時(shí)間w,若在w時(shí)間內(nèi),即等待還未結(jié)束時(shí),函數(shù)又被調(diào)用了一次,則再等待w時(shí)間,重復(fù)上述過程,直到最后一次被調(diào)用后的w時(shí)間內(nèi)該函數(shù)都沒有被再調(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ù)是僅僅會被執(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í)行過一次后,參數(shù)fn就被賦值null了,那么在接下來被調(diào)用時(shí),便再也不會進(jìn)入到if語句中了,也就是第一次被調(diào)用后,該函數(shù)永遠(yuǎn)不會被執(zhí)行了。

還可以對上述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é)語

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

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/87278.html

相關(guān)文章

  • 談?wù)?/em>JavaScript的詞法環(huán)境和閉包(一)

    摘要:換句話說,定義在閉包中的函數(shù)可以記憶它被創(chuàng)建時(shí)候的環(huán)境。詞法環(huán)境的概念定義摘自百科。一個詞法環(huán)境由一個環(huán)境記錄項(xiàng)和可能為空的外部詞法環(huán)境引用構(gòu)成。中使用詞法環(huán)境管理靜態(tài)作用域。 一個資深的同事在我出發(fā)去面試前告誡我,問JS知識點(diǎn)的時(shí)候千萬別主動提閉包,它就是一個坑啊!坑啊!啊! 閉包確實(shí)是js的難點(diǎn)和重點(diǎn),其實(shí)也沒那么可怕,關(guān)鍵是機(jī)制的理解,可以和函數(shù)一起單獨(dú)拿出來說說,其實(shí)關(guān)于閉包的...

    AlphaWatch 評論0 收藏0
  • 金三銀四,2019大廠Android高級工程師面試題整理

    摘要:原文地址游客前言金三銀四,很多同學(xué)心里大概都準(zhǔn)備著年后找工作或者跳槽。最近有很多同學(xué)都在交流群里求大廠面試題。 最近整理了一波面試題,包括安卓JAVA方面的,目前大廠還是以安卓源碼,算法,以及數(shù)據(jù)結(jié)構(gòu)為主,有一些中小型公司也會問到混合開發(fā)的知識,至于我為什么傾向于混合開發(fā),我的一句話就是走上編程之路,將來你要學(xué)不僅僅是這些,豐富自己方能與世接軌,做好全棧的裝備。 原文地址:游客kutd...

    tracymac7 評論0 收藏0
  • 談?wù)?/em>一些關(guān)于mgo的用法

    摘要:在這里談一談實(shí)踐過程中遇到的問題,基礎(chǔ)的用法不再說明了,可以自行百度。一般傳入的參數(shù)為。當(dāng)然中的聚合命令不止這些,用法大同小異如果要實(shí)現(xiàn)一些高級功能,的基本命令滿足不了你,可能就要使用這個了。 前言 最近在項(xiàng)目中使用mongodb進(jìn)行簡單的數(shù)據(jù)分析,在使用mongodb驅(qū)動mgo時(shí)遇到一些問題,比如在mongodb中執(zhí)行命令成功,到了mgo中就執(zhí)行失敗。在這里談一談實(shí)踐過程中遇到的問題...

    李世贊 評論0 收藏0
  • 談?wù)?/em>javascript插件的寫法

    插件顧名思義就是能在一個頁面多處使用, 各自按自己的參數(shù)配置運(yùn)行, 并且相互不會沖突.會寫javascript插件是進(jìn)階js高級的必經(jīng)之路, 也是自己所學(xué)知識的一個典型的綜合運(yùn)用. 如果你還沒頭緒, 無從下手的話, 不用著急, 今天我們就一起來探討一下插件的一般寫法.所需技能: 1.面向?qū)ο笥梅?2.閉包的理解 3.變量作用域的理解 以一個tab選項(xiàng)卡的為例: 第一步: 我們需要寫html結(jié)...

    lakeside 評論0 收藏0

發(fā)表評論

0條評論

raoyi

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<