成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Javascript中的魔鬼

daydream / 1824人閱讀

摘要:發(fā)生這個(gè)異常的原因就是因?yàn)樵谡{(diào)用函數(shù)時(shí),中的已經(jīng)不再指向?qū)ο蠖侵赶蛄巳謱?duì)象,由于下并沒有屬性,所以輸出。在為綁定的上下文環(huán)境之后,并不會(huì)立即執(zhí)行。方法用于檢查數(shù)組中的是否存在符合條件的項(xiàng),存在則返回否則返回。

寫作意圖

這篇文章用于總結(jié)一些javascript語(yǔ)言中常見的易混淆點(diǎn)。

call | apply | bind

在js中,最詭異莫測(cè)的莫過(guò)于this了,理解的不夠深入或是應(yīng)用場(chǎng)景略微復(fù)雜,使用時(shí)就會(huì)出現(xiàn)各種意想不到的錯(cuò)誤。所以,在很多時(shí)候,我們需要手動(dòng)指定上下文環(huán)境,來(lái)修正this的指向。
最簡(jiǎn)單判斷this所在環(huán)境的方法是,尋找this的實(shí)際調(diào)用者。

一個(gè)典型的錯(cuò)誤
    var a = {
        name: "ein",
        sayName: function () {
            console.log(this.name);
        }
    }

    var b = a.sayName;
    b();  //undefined

我們本想將對(duì)象a的sayName賦值給變量b,通過(guò)調(diào)用來(lái)查看a的name是什么?結(jié)果卻輸出了undefined。發(fā)生這個(gè)異常的原因就是因?yàn)樵谡{(diào)用函數(shù)b時(shí),sayName中的this已經(jīng)不再指向?qū)ο骯而是指向了全局對(duì)象window,由于window下并沒有name屬性,所以輸出undefined。

下面我們將通過(guò)以上三種方法來(lái)修正這個(gè)問(wèn)題。

使用call
    var b = a.sayName;
    b.call(a);  //ein

使用call方法,第一個(gè)參數(shù)為函數(shù)調(diào)用時(shí)的上下文環(huán)境,將其設(shè)定為對(duì)象a,這樣this就會(huì)指向?qū)ο骯,如此便可以取到對(duì)象a中的name屬性,輸出想要的值。

使用apply
    var b = a.sayName;
    b.apply(a); //ein

使用apply方法,傳入上下文環(huán)境,可以實(shí)現(xiàn)同樣的效果。

call和apply的區(qū)別

那么call和apply的區(qū)別是什么呢?他們的區(qū)別在于后續(xù)的參數(shù)。讓我們改造一下上面的代碼,來(lái)觀察效果。

    var a = {
        name: "ein",
        sayName: function (fistname, lastname) {
            console.log(`${fistname} ${this.name} ${lastname}`);
        }
    }

    var b = a.sayName;

    b.call(a,"nick","snow");  //nick ein snow
    b.apply(a,["nick","snow"]);  //nick ein snow

call和apply的區(qū)別在于后續(xù)參數(shù),call依次傳入后續(xù)參數(shù),將被函數(shù)所使用。apply需要將后續(xù)參數(shù)以數(shù)組的形式傳入。

使用bind

bind同樣可以用來(lái)修正this的指向,它與以上二者的區(qū)別在于,bind綁定之后并不會(huì)立即執(zhí)行函數(shù)。

    var b = a.sayName;
    b.bind(a);

在為b綁定a的上下文環(huán)境之后,b并不會(huì)立即執(zhí)行。

    b.bind(a,"nick","snow")();  //nick ein snow
    var c = b.bind(a);
    c("nick","snow");  //nick ein snow

如此,便可以如愿得到你想要的效果了。使用bind方法可以延緩函數(shù)的執(zhí)行時(shí)間,在你想調(diào)用時(shí)再執(zhí)行函數(shù)。
bind方法同樣可以傳入其它參數(shù),和call方法的傳入方式相同。

splice | slice | split

看到這三個(gè)方法有沒有頭暈?zāi)垦5母杏X?因?yàn)樗鼈內(nèi)齻€(gè)實(shí)在是太像三胞胎了,真的很難區(qū)分。首先,我們來(lái)學(xué)習(xí)或是回顧一下這三個(gè)單詞。

splice  拼接  
slice   片,切片  
split   分裂,裂開

大多數(shù)api其實(shí)其名稱都與其用途有所關(guān)聯(lián),這三個(gè)api便是很經(jīng)典的案例。

splice意為拼接,它的用途,便是將一個(gè)數(shù)組分割開,并且可以再以指定的方式重新拼接在一起。

slice意為切片,我們可以使用它來(lái)在一個(gè)數(shù)組或是字符串中切取我們想要的一段。

split意為分裂,它可以將一個(gè)字符串分裂成一個(gè)數(shù)組。

使用splice
    var a = [1,2,3,4,5];
    a.splice(1,2,4,4);
    console.log(a);
    //[1,4,4,4,5]

splice(starts, count, item1, ..., itemx)方法接受多個(gè)參數(shù),第一個(gè)參數(shù)為刪除的起始元素,第二個(gè)參數(shù)為刪除數(shù)量,后續(xù)為插入的內(nèi)容。
注意: splice方法會(huì)修改原始數(shù)組,返回被刪除的內(nèi)容數(shù)組。

使用slice
    var a = [1,2,3,4,5];
    var b = "12345";
    a.slice(1,3);  //[2,3]
    a.slice(1);  //[2,3,4,5]
    a.slice(2,-1)  //[3,4]
    b.slice(1,2);  //"2"
    console.log(a);  //[1,2,3,4,5]
    console.log(b);  //"12345"

slice方法既可應(yīng)用于數(shù)組也可應(yīng)用于字符串。

slice(stats, beforeEnds)方法接受最多兩個(gè)參數(shù),第一個(gè)參數(shù)代表的序列號(hào)必須小于第二個(gè)參數(shù),第二個(gè)參數(shù)為切片的終止位置,第二個(gè)參數(shù)省略時(shí)默認(rèn)截取到數(shù)據(jù)末尾,參數(shù)為負(fù)數(shù)時(shí),將反向查找匹配項(xiàng)。

注意: slice方法不會(huì)修改原始數(shù)組,返回的是被切片節(jié)選的片段。

使用split
    var a = "123456";
    a.split("");  //["1","2","3","4","5","6"]
    a.split("",3);  //["1","2","3"]
    console.log(a);  //"123456"

split(separator, count)方法可接受兩個(gè)參數(shù),第一個(gè)參數(shù)為分割符,用于指定字符串的分割規(guī)則,第二個(gè)參數(shù)為返回?cái)?shù)組的最大長(zhǎng)度,返回的輸出長(zhǎng)度不會(huì)大于這個(gè)參數(shù)。
注意: split不會(huì)修改原始字符串,返回值為新數(shù)組。

map | forEach | reduce | filter | every | some

這六個(gè)方法時(shí)常用的操作數(shù)組的api,均為Array.prototype的本地方法。所以一切數(shù)組均可使用這些方法遍歷操作數(shù)組的每一項(xiàng),下面將逐一介紹這些方法。

map
    var arr = [
        {"name": "ein"},
        {"name": "zwei"},
        {"name": "drei"}
    ];

    let newarr = arr.map((item, index) => {
        return (
            {
                "name": item.name,
                "order": index
            }
        )
    });
    console.log(arr);
    // [{"name": "ein"},{"name": "zwei"},{"name": "drei"}] 
    console.log(newarr);
    // [{"name": "ein","order": 0},{"name": "zwei","order": 1},{"name": "drei","order": 2}]

map(fn(item, index))方法接收一個(gè)函數(shù)作為參數(shù),這個(gè)函數(shù)接收兩個(gè)參數(shù),第一個(gè)參數(shù)為每一項(xiàng)的數(shù)組內(nèi)容,第二個(gè)參數(shù)為數(shù)組下標(biāo)。
注意: map方法返回一個(gè)新的數(shù)組,如果在操作中沒有return返回值,默認(rèn)返回一個(gè)值為undefined的數(shù)組。
默認(rèn)返回:[undefined, undefined, undefined]

forEach
    arr.forEach((item, index) => {
        item.old = true;
        delete item.name;
    })
    console.log(arr);
    //  [{"old": true},{"old": true},{"old": true}]

forEach(fn(item, index))方法接收一個(gè)函數(shù)作為參數(shù),這個(gè)函數(shù)接收兩個(gè)參數(shù),第一個(gè)參數(shù)為每一項(xiàng)的數(shù)組內(nèi)容,第二個(gè)參數(shù)為數(shù)組下標(biāo)。
注意: forEach方法直接操作原始數(shù)組,并且不返回任何內(nèi)容。

reduce

簡(jiǎn)單用例

    var arr1 = [1,2,3,4,5];
    var res = arr1.reduce((curr, next) => {
        return curr + next
    });
    console.log(res);  //15
    console.log(arr1);  //[1, 2, 3, 4, 5]

復(fù)雜用例

    var res1 = arr1.reduce((curr, next,index,arr) => {
        console.log("content",curr,next,index,arr);
        return curr + next
    },10);
    console.log(res1);
content 初始值(curr) 當(dāng)前元素(next) 當(dāng)前元素索引(index) 當(dāng)前元素所屬數(shù)組(arr) 函數(shù)初始值
content 10 1 0 ?[1, 2, 3, 4, 5] 10
content 11 2 1 ?[1, 2, 3, 4, 5] 10
content 13 3 2 ?[1, 2, 3, 4, 5] 10
content 16 4 3 ?[1, 2, 3, 4, 5] 10
content 20 5 4 ?[1, 2, 3, 4, 5] 10

reduce方法用于對(duì)數(shù)組進(jìn)行累積化操作,常用于數(shù)組求和。接收兩個(gè)參數(shù),第一個(gè)參數(shù)為操作函數(shù),第二個(gè)參數(shù)為函數(shù)初始值。對(duì)于數(shù)組的操作不會(huì)修改原始值。

filter
    var res = arr1.filter((item, index) => {
        console.log("data:",index,item);
        return item > 3
    });
    console.log(res);
    //  [4, 5]

filter方法用于過(guò)濾數(shù)組的每一項(xiàng),刪選出符合條件的項(xiàng),并組成一個(gè)新的數(shù)組。

every
    var res = arr1.every((item, index) => {
        return item > 3
    });
    console.log(res);
    // false

every方法用于檢查數(shù)組的每一項(xiàng)是否符合條件,全部符合條件時(shí)返回true,否則返回false。

some
    var res = arr1.some((item, index) => {
        return item > 3
    });
    console.log(res);
    // true

some方法用于檢查數(shù)組中的是否存在符合條件的項(xiàng),存在則返回true,否則返回false。

另外

一副生動(dòng)有趣的圖解,everyday will be better!

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93944.html

相關(guān)文章

  • eval()不是魔鬼,只是被誤解了(翻譯)

    摘要:因?yàn)榈栏窭沟拇蠖鄶?shù)作品并沒有注明日期,所以,我不確定他是否是在年創(chuàng)造了這個(gè)術(shù)語(yǔ)。但這并不能說(shuō)明是魔鬼,這只是開發(fā)工作流程中的一點(diǎn)問(wèn)題。中間人攻擊被認(rèn)為是的永遠(yuǎn)存在的危險(xiǎn),會(huì)受到蠕蟲的的攻擊。 原文來(lái)自:https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/ 作者:Nicholas C.Z...

    elarity 評(píng)論0 收藏0
  • JS學(xué)習(xí)筆記 - eval() 是魔鬼

    摘要:要牢記使用這些構(gòu)造函數(shù)來(lái)傳遞參數(shù),在大部分情況下,會(huì)導(dǎo)致類似的隱患,因此應(yīng)該也盡量避免使用這些函數(shù)。下面一個(gè)栗子使用構(gòu)造函數(shù)和是比較類似的,因此該函數(shù)的使用也需要十分小心。 本文章記錄本人在學(xué)習(xí) JavaScript 中看書理解到的一些東西,加深記憶和并且整理記錄下來(lái),方便之后的復(fù)習(xí)。 小白使用 eval() 如果在代碼中使用了eval(),請(qǐng)記住一句話:eval()是一個(gè)...

    mengera88 評(píng)論0 收藏0
  • 前端性能優(yōu)化(JavaScript篇)

    摘要:像也是類似的也不建議使用,會(huì)降低性能,通過(guò)包裹的代碼塊,作用域鏈將會(huì)額外增加一層,降低索引效率對(duì)象的優(yōu)化緩存需要被使用的對(duì)象獲取數(shù)據(jù)的性能有如下順序從快到慢變量獲取數(shù)組下標(biāo)獲取對(duì)象的整數(shù)索引獲取對(duì)象屬性獲取對(duì)象非整數(shù)索引獲取。 正巧看到在送書,于是乎找了找自己博客上記錄過(guò)的一些東西來(lái)及其無(wú)恥的蹭書了~~~ 小廣告:更多內(nèi)容可以看我的博客 優(yōu)化循環(huán) 如果現(xiàn)在有個(gè)一個(gè)data[]數(shù)組...

    KunMinX 評(píng)論0 收藏0
  • 前端性能優(yōu)化(JavaScript篇)

    摘要:像也是類似的也不建議使用,會(huì)降低性能,通過(guò)包裹的代碼塊,作用域鏈將會(huì)額外增加一層,降低索引效率對(duì)象的優(yōu)化緩存需要被使用的對(duì)象獲取數(shù)據(jù)的性能有如下順序從快到慢變量獲取數(shù)組下標(biāo)獲取對(duì)象的整數(shù)索引獲取對(duì)象屬性獲取對(duì)象非整數(shù)索引獲取。 正巧看到在送書,于是乎找了找自己博客上記錄過(guò)的一些東西來(lái)及其無(wú)恥的蹭書了~~~ 小廣告:更多內(nèi)容可以看我的博客 優(yōu)化循環(huán) 如果現(xiàn)在有個(gè)一個(gè)data[]數(shù)組...

    kun_jian 評(píng)論0 收藏0
  • 重塑你的CSS世界觀——浮動(dòng)魔鬼float

    摘要:而在文檔流中,如果浮動(dòng)元素和跟隨元素都是元素,它們兩在默認(rèn)情況下都將占據(jù)一行。而由于浮動(dòng)元素脫離了文檔流,如果父元素沒有指定高度或者其他元素?fù)纹穑簿统霈F(xiàn)了所謂的浮動(dòng)元素的父元素高度塌陷。 為什么要寫《重塑你的CSS世界觀》系列文章 由于從工作到現(xiàn)在,我的主要工作都是寫JavaScript,幾乎沒怎么碰CSS,通常都是別人寫好界面,然后我來(lái)開發(fā)JavaScript邏輯代碼,這導(dǎo)致了嚴(yán)重...

    joyqi 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<