摘要:發(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)用者。
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)題。
使用callvar 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屬性,輸出想要的值。
使用applyvar 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ù)組的形式傳入。
使用bindbind同樣可以用來(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方法的傳入方式相同。
看到這三個(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ù)組。
使用splicevar 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ù)組。
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é)選的片段。
使用splitvar 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ù)組。
這六個(gè)方法時(shí)常用的操作數(shù)組的api,均為Array.prototype的本地方法。所以一切數(shù)組均可使用這些方法遍歷操作數(shù)組的每一項(xiàng),下面將逐一介紹這些方法。
mapvar 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]
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)容。
簡(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ì)修改原始值。
filtervar 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ù)組。
everyvar res = arr1.every((item, index) => { return item > 3 }); console.log(res); // false
every方法用于檢查數(shù)組的每一項(xiàng)是否符合條件,全部符合條件時(shí)返回true,否則返回false。
somevar 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
摘要:因?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...
摘要:要牢記使用這些構(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è)...
摘要:像也是類似的也不建議使用,會(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ù)組...
摘要:像也是類似的也不建議使用,會(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ù)組...
摘要:而在文檔流中,如果浮動(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)重...
閱讀 1129·2021-10-14 09:43
閱讀 1185·2021-10-11 11:07
閱讀 3133·2021-08-18 10:23
閱讀 1516·2019-08-29 16:18
閱讀 1032·2019-08-28 18:21
閱讀 1501·2019-08-26 12:12
閱讀 3789·2019-08-26 10:11
閱讀 2534·2019-08-23 18:04