面試題聯(lián)盟之 JS 篇
關(guān)注 入坑互聯(lián)網(wǎng) ,回復(fù)“加群”
加入我們一起學(xué)習(xí),天天進(jìn)步
1.閉包理解
父函數(shù)將子函數(shù)作為返回值,再將子函數(shù)賦值給一個(gè)變量,所以子函數(shù)會(huì)存在于內(nèi)存中,而子函數(shù)依賴于父函數(shù)存在,所以父函數(shù)也會(huì)存在于內(nèi)存中,也就不會(huì)被垃圾回收機(jī)制回收。
1: let val = 72: function createAdder() {3: function addNumbers(a, b) {4: let ret = a + b5: return ret6: }7: return addNumbers8:}9: let adder = createAdder()10: let sum = adder(val, 8)11: console.log('example of function returning a function: ', sum)
2.繼承鏈的理解(原型鏈)
每一個(gè)對(duì)象都有一個(gè)“proto”指針,指向?qū)嵗搶?duì)象的構(gòu)造函數(shù)的原型對(duì)象,當(dāng)該對(duì)象沒(méi)有你想拿到的屬性時(shí),解釋器會(huì)順著指針不斷向上找。
每一個(gè)構(gòu)造你函數(shù)都有一個(gè)“prototype”屬性,指向該構(gòu)造函數(shù)的原型對(duì)象。
每一個(gè)原型對(duì)象都有一個(gè)“constructor”屬性,指向該原型對(duì)象的構(gòu)造函數(shù)。
任何對(duì)象(全局對(duì)象除外)向上查找的終點(diǎn)都是全局對(duì)象下的 Object 構(gòu)造函數(shù)的原型對(duì)象。
3.對(duì)像合并?數(shù)組去重過(guò)濾?
對(duì)象合并:Object.assign(form, obj)----->Object.assign(目標(biāo)對(duì)象, 被合并的對(duì)象)、$.extend、
數(shù)組去重:Set、filter、Map
4.http 狀態(tài)碼有哪幾種?常用的狀態(tài)碼表示什么?
200("OK")
一切正常。實(shí)體主體中的文檔(若存在的話)是某資源的表示。
400("Bad Request")
客戶端方面的問(wèn)題。實(shí)體主題中的文檔(若存在的話)是一個(gè)錯(cuò)誤消息。希望客戶端能夠理解此錯(cuò)誤消息,并改正問(wèn)題。
500("Internal Server Error")
服務(wù)期方面的問(wèn)題。實(shí)體主體中的文檔(如果存在的話)是一個(gè)錯(cuò)誤消息。該錯(cuò)誤消息通常無(wú)濟(jì)于事,因?yàn)榭蛻舳藷o(wú)法修復(fù)服務(wù)器方面的問(wèn)題。
301("Moved Permanently")
當(dāng)客戶端觸發(fā)的動(dòng)作引起了資源 URI 的變化時(shí)發(fā)送此響應(yīng)代碼。另外,當(dāng)客戶端向一個(gè)資源的舊 URI 發(fā)送請(qǐng)求時(shí),也發(fā)送此響應(yīng)代碼。
404("Not Found") 和 410("Gone")
當(dāng)客戶端所請(qǐng)求的 URI 不對(duì)應(yīng)于任何資源時(shí),發(fā)送此響應(yīng)代碼。404 用于服務(wù)器端不知道客戶端要請(qǐng)求哪個(gè)資源的情況;410 用于服務(wù)器端知道客戶端所請(qǐng)求的資源曾經(jīng)存在,但現(xiàn)在已經(jīng)不存在了的情況。
409("Conflict")
當(dāng)客戶端試圖執(zhí)行一個(gè)”會(huì)導(dǎo)致一個(gè)或多個(gè)資源處于不一致?tīng)顟B(tài)“的操作時(shí),發(fā)送此響應(yīng)代碼。
5.跨域的理解?常見(jiàn)的跨域處理有哪一些?\
瀏覽器為隔離潛在的惡意文件,限制了從同一個(gè)源加載的文檔或腳本如何與來(lái)自另一個(gè)源的資源進(jìn)行交互,所以,是瀏覽器的基于安全考慮的同源策略導(dǎo)致的跨域
解決一:
JSONP,script 的 src 屬性不受限制,但是只能進(jìn)行 get 請(qǐng)求,
jQuery 將 jsonp 封裝進(jìn)了 ajax,首先 jsonp 只支持 get 請(qǐng)求,所以所有傳入的參數(shù)都是 http://xxx.xxx.xxx/xxx/xxx?xxx=1&&yyy=2 這種形式;其次在 dataType 屬性必須設(shè)置為 jsonp,jquery 是支持 jsonp 的。
$.ajax("http://xxx.xxx.xxx/xxx/xxx", {type: 'get',dataType: "jsonp",data : reqDatasuccess: function(data) {console.log(data);},error: function(xhr, type, errorThrown) {console.log(xhr.statusText);plus.nativeUI.toast("fail");}});
解決二:直接在服務(wù)器端設(shè)置跨域資源訪問(wèn) CORS(Cross-Origin Resource Sharing),設(shè)置 Request Header 頭中 Access-Control-Allow-Origin 為指定可獲取數(shù)據(jù)的域名(常用)
解決三:使用 Nginx 反向代理
解決四:webpack 代理(只適用于本地環(huán)境)
解決五:nodejs 反向代理
6.seo 優(yōu)化的理解?(加分項(xiàng))
① 提高頁(yè)面加載速度。能用 css 解決的不用背景圖片,背景圖片也盡量壓縮大小,可以幾個(gè) icons 放在一個(gè)圖片上,使用 background-position 找到需要的圖片位置??梢詼p少 HTTP 請(qǐng)求數(shù),提高網(wǎng)頁(yè)加載速度。
② 結(jié)構(gòu)、表現(xiàn)和行為的分離。另外一個(gè)重要的拖慢網(wǎng)頁(yè)加載速度的原因就是將 css 和 JS 都堆積在 HTML 頁(yè)面上,每次看到有人直接在頁(yè)面上編寫(xiě) CSS 和 JS 我都很痛心疾首。通過(guò)外鏈的方式能大大加快網(wǎng)頁(yè)加載速度的,css 文件可以放在 head 里,JS 文件可以放置在 body 的最下方,在不影響閱讀的情況下再去加載 JS 文件。
③ 優(yōu)化網(wǎng)站分級(jí)結(jié)構(gòu)。在每個(gè)內(nèi)頁(yè)加面包屑導(dǎo)航是很有必要的,可以讓蜘蛛進(jìn)入頁(yè)面之后不至于迷路,有條件的話,最好能單獨(dú)加個(gè) Sitemap 頁(yè)面,將網(wǎng)站結(jié)構(gòu)一目了然地展示在蜘蛛面前,更有利于蜘蛛抓取信息。
④ 集中網(wǎng)站權(quán)重。由于蜘蛛分配到每個(gè)頁(yè)面的權(quán)重是一定的,這些權(quán)重也將平均分配到每個(gè) a 鏈接上,那么為了集中網(wǎng)站權(quán)重,可以使用”rel=nofollow”屬性,它告訴蜘蛛無(wú)需抓取目標(biāo)頁(yè),可以將權(quán)重分給其他的鏈接。
⑤ 文本強(qiáng)調(diào)標(biāo)簽的使用。當(dāng)著重強(qiáng)調(diào)某個(gè)關(guān)鍵詞需要加粗表示,選用 strong 標(biāo)簽比使用 b 標(biāo)簽要更有強(qiáng)調(diào)作用。
⑥ a 標(biāo)簽的 title 屬性的使用。在不影響頁(yè)面功能的情況下,可以盡量給 a 標(biāo)簽加上 title 屬性,可以更有利于蜘蛛抓取信息。
⑦ 圖片 alt 屬性的使用。這個(gè)屬性可以在圖片加載不出來(lái)的時(shí)候顯示在頁(yè)面上相關(guān)的文字信息,作用同上。
⑧ H 標(biāo)簽的使用。主要是 H1 標(biāo)簽的使用需要特別注意,因?yàn)樗詭?quán)重,一個(gè)頁(yè)面有且最多只能有一個(gè) H1 標(biāo)簽,放在該頁(yè)面最重要的標(biāo)題上面,如首頁(yè)的 logo 上可以加 H1 標(biāo)簽。
7.對(duì)象深拷貝、淺拷貝
淺拷貝:當(dāng)拷貝完一個(gè)對(duì)象的時(shí)候,其中一個(gè)對(duì)象的數(shù)據(jù)發(fā)生了變化,另一個(gè)對(duì)象的數(shù)據(jù)也會(huì)發(fā)生變化,因?yàn)闇\拷貝拷貝的是索引
深拷貝:當(dāng)拷貝完一個(gè)對(duì)象的時(shí)候,其中一個(gè)對(duì)象的數(shù)據(jù)發(fā)生了變化,另外一個(gè)對(duì)象的數(shù)據(jù) 不會(huì)發(fā)生變化,因?yàn)樯羁截惪截惖氖菙?shù)值
8.js 異步加載的方式
① <script>標(biāo)簽的async="async"屬性<script type="text/javascript" src="xxx.js"async="async"></script>② onload時(shí)的異步加載(這種方法只是把插入script的方法放在一個(gè)函數(shù)里面,然后放在window的onload方法里面執(zhí)行,這樣就解決了阻塞onload事件觸發(fā)的問(wèn)題。)③ $(document).ready(function() {alert("加載完成!") })④ <script>標(biāo)簽的defer="defer"屬性<script type="text/javascript" defer></script>
9.babel 原理
ES6、7代碼輸入 -> babylon進(jìn)行解析 -> 得到AST(抽象語(yǔ)法樹(shù))-> plugin用babel-traverse對(duì)AST樹(shù)進(jìn)行遍歷轉(zhuǎn)譯 ->得到新的AST樹(shù)->用babel-generator通過(guò)AST樹(shù)生成ES5代碼10.JavaScript 中的強(qiáng)制轉(zhuǎn)型(coercion)是指什么?
在 JavaScript 中,兩種不同的內(nèi)置類型間的轉(zhuǎn)換被稱為強(qiáng)制轉(zhuǎn)型。強(qiáng)制轉(zhuǎn)型在 JavaScript 中有兩種形式:顯式和隱式。
顯式強(qiáng)制轉(zhuǎn)型
var a = "42";var b = Number( a );a; // "42" -- 字符串b; // 42 -- 是個(gè)數(shù)字!
這是一個(gè)隱式強(qiáng)制轉(zhuǎn)型的例子:
var a = "42";var b = a * 1; // "42" 隱式轉(zhuǎn)型成 42a; // "42"b; // 42 -- 是個(gè)數(shù)字!
11.JavaScript 中的作用域(scope)是指什么?
在 JavaScript 中,每個(gè)函數(shù)都有自己的作用域。作用域基本上是變量以及如何通過(guò)名稱訪問(wèn)這些變量的規(guī)則的集合。只有函數(shù)中的代碼才能訪問(wèn)函數(shù)作用域內(nèi)的變量。
同一個(gè)作用域中的變量名必須是唯一的。一個(gè)作用域可以嵌套在另一個(gè)作用域內(nèi)。如果一個(gè)作用域嵌套在另一個(gè)作用域內(nèi),最內(nèi)部作用域內(nèi)的代碼可以訪問(wèn)另一個(gè)作用域的變量。
12.“use strict”的作用是什么?
use strict 出現(xiàn)在 JavaScript 代碼的頂部或函數(shù)的頂部,可以幫助你寫(xiě)出更安全的 JavaScript 代碼。如果你錯(cuò)誤地創(chuàng)建了全局變量,它會(huì)通過(guò)拋出錯(cuò)誤的方式來(lái)警告你。例如,以下程序?qū)伋鲥e(cuò)誤:
function doSomething(val) {"use strict";x = val + 10;}
復(fù)制代碼它會(huì)拋出一個(gè)錯(cuò)誤,因?yàn)?x 沒(méi)有被定義,并使用了全局作用域中的某個(gè)值對(duì)其進(jìn)行賦值,而 use strict 不允許這樣做。下面的小改動(dòng)修復(fù)了這個(gè)錯(cuò)誤:
function doSomething(val) {"use strict";var x = val + 10;}
13.JavaScript 中的 let 關(guān)鍵字有什么用?
除了可以在函數(shù)級(jí)別聲明變量之外,ES6 還允許你使用 let 關(guān)鍵字在代碼塊({..})中聲明變量。
14.什么是防抖和節(jié)流?有什么區(qū)別?如何實(shí)現(xiàn)?
防抖
觸發(fā)高頻事件后 n 秒內(nèi)函數(shù)只會(huì)執(zhí)行一次,如果 n 秒內(nèi)高頻事件再次被觸發(fā),則重新計(jì)算時(shí)間;
思路:每次觸發(fā)事件時(shí)都取消之前的延時(shí)調(diào)用方法:
function debounce(fn) {let timeout = null; // 創(chuàng)建一個(gè)標(biāo)記用來(lái)存放定時(shí)器的返回值return function () {clearTimeout(timeout); // 每當(dāng)用戶輸入的時(shí)候把前一個(gè) setTimeout clear 掉timeout = setTimeout(() => {// 然后又創(chuàng)建一個(gè)新的 setTimeout// 這樣就能保證輸入字符后的 interval 間隔內(nèi)如果還有字符輸入的話,就不會(huì)執(zhí)行 fn 函數(shù)fn.apply(this, arguments);}, 500);};}function sayHi() {console.log('防抖成功');}var inp = document.getElementById('inp');inp.addEventListener('input', debounce(sayHi)); // 防抖
代碼節(jié)流
高頻事件觸發(fā),但在 n 秒內(nèi)只會(huì)執(zhí)行一次,所以節(jié)流會(huì)稀釋函數(shù)的執(zhí)行頻率。
思路:每次觸發(fā)事件時(shí)都判斷當(dāng)前是否有等待執(zhí)行的延時(shí)函數(shù)。
function throttle(fn) {let canRun = true; // 通過(guò)閉包保存一個(gè)標(biāo)記return function () {if (!canRun) return; // 在函數(shù)開(kāi)頭判斷標(biāo)記是否為 true,不為 true 則 returncanRun = false; // 立即設(shè)置為 falsesetTimeout(() => { // 將外部傳入的函數(shù)的執(zhí)行放在 setTimeout 中fn.apply(this, arguments);// 最后在 setTimeout 執(zhí)行完畢后再把標(biāo)記設(shè)置為 true(關(guān)鍵) 表示可以執(zhí)行下一次循環(huán)了// 當(dāng)定時(shí)器沒(méi)有執(zhí)行的時(shí)候標(biāo)記永遠(yuǎn)是 false,在開(kāi)頭被 return 掉canRun = true;}, 500);};}function sayHi(e) {console.log(e.target.innerWidth, e.target.innerHeight);}window.addEventListener('resize', throttle(sayHi));
15.介紹下 Set、Map、WeakSet 和 WeakMap 的區(qū)別?
Set
成員唯一、無(wú)序且不重復(fù);
[value, value],鍵值與鍵名是一致的(或者說(shuō)只有鍵值,沒(méi)有鍵名);
可以遍歷,方法有:add、delete、has。
WeakSet
成員都是對(duì)象;
成員都是弱引用,可以被垃圾回收機(jī)制回收,可以用來(lái)保存 DOM 節(jié)點(diǎn),不容易造成內(nèi)存泄漏;
不能遍歷,方法有 add、delete、has。
Map
本質(zhì)上是鍵值對(duì)的集合,類似集合;
可以遍歷,方法很多,可以跟各種數(shù)據(jù)格式轉(zhuǎn)換。
WeakMap
只接受對(duì)象最為鍵名(null 除外),不接受其他類型的值作為鍵名;
鍵名是弱引用,鍵值可以是任意的,鍵名所指向的對(duì)象可以被垃圾回收,此時(shí)鍵名是無(wú)效的;
不能遍歷,方法有 get、set、has、delete。
16.JS 異步解決方案
回調(diào)函數(shù)(callback)
setTimeout(() => {// callback 函數(shù)體}, 1000)
缺點(diǎn):回調(diào)地獄,不能用 try catch 捕獲錯(cuò)誤,不能 return
回調(diào)地獄的根本問(wèn)題在于:
缺乏順序性:回調(diào)地獄導(dǎo)致的調(diào)試?yán)щy,和大腦的思維方式不符;
嵌套函數(shù)存在耦合性,一旦有所改動(dòng),就會(huì)牽一發(fā)而動(dòng)全身,即(控制反轉(zhuǎn));
嵌套函數(shù)過(guò)多的多話,很難處理錯(cuò)誤。
ajax('XXX1', () => {// callback 函數(shù)體ajax('XXX2', () => {// callback 函數(shù)體ajax('XXX3', () => {// callback 函數(shù)體})})})
Promise
Promise 就是為了解決 callback 的問(wèn)題而產(chǎn)生的。
Promise 實(shí)現(xiàn)了鏈?zhǔn)秸{(diào)用,也就是說(shuō)每次 then 后返回的都是一個(gè)全新 Promise,如果我們?cè)?then 中 return ,return 的結(jié)果會(huì)被 Promise.resolve() 包裝。
優(yōu)點(diǎn):解決了回調(diào)地獄的問(wèn)題。
ajax('XXX1').then(res => {// 操作邏輯return ajax('XXX2')}).then(res => {// 操作邏輯return ajax('XXX3')}).then(res => {// 操作邏輯})
Generator
特點(diǎn):可以控制函數(shù)的執(zhí)行,可以配合 co.js 函數(shù)庫(kù)使用。(也就是 koa 早期使用的庫(kù))
function \*fetch() {yield ajax('XXX1', () => {})yield ajax('XXX2', () => {})yield ajax('XXX3', () => {})}let it = fetch()let result1 = it.next()let result2 = it.next()let result3 = it.next()
Async/await
async、await 是異步的終極解決方案。
優(yōu)點(diǎn)是:代碼清晰,不用像 Promise 寫(xiě)一大堆 then 鏈,處理了回調(diào)地獄的問(wèn)題;
缺點(diǎn):await 將異步代碼改造成同步代碼,如果多個(gè)異步操作沒(méi)有依賴性而使用 await 會(huì)導(dǎo)致性能上的降低。
async function test() {// 以下代碼沒(méi)有依賴性的話,完全可以使用 Promise.all 的方式// 如果有依賴性的話,其實(shí)就是解決回調(diào)地獄的例子了await fetch('XXX1')await fetch('XXX2')await fetch('XXX3')}
下面來(lái)看一個(gè)使用 await 的例子:
let a = 0let b = async () => {a = a + await 10console.log('2', a) // -> '2' 10}b()a++console.log('1', a) // -> '1' 1
上述解釋中提到了 await 內(nèi)部實(shí)現(xiàn)了 generator,其實(shí) await 就是 generator 加上 Promise 的語(yǔ)法糖,且內(nèi)部實(shí)現(xiàn)了自動(dòng)執(zhí)行 generator。如果你熟悉 co 的話,其實(shí)自己就可以實(shí)現(xiàn)這樣的語(yǔ)法糖。
17.如何理解 JS 中的this關(guān)鍵字?
“this” 一般是表示當(dāng)前所在的對(duì)象,但是事情并沒(méi)有像它應(yīng)該的那樣發(fā)生。JS中的this關(guān)鍵字由函數(shù)的調(diào)用者決定,誰(shuí)調(diào)用就this就指向哪個(gè)。如果找不到調(diào)用者,this將指向windows對(duì)象。
第一個(gè)例子很簡(jiǎn)單。調(diào)用 test對(duì)象中的 func(),因此func() 中的'this'指向的是 test 對(duì)象,所以打印的 prop 是 test 中的 prop,即 42。
var test = {prop: 42,func: function(){return this.prop;},};console.log (test.func()); // 42
如果我們直接調(diào)用getFullname函數(shù),第二個(gè)例子將打印出'David Jones',因?yàn)榇藭r(shí) this 找不到調(diào)用者,所以默認(rèn)就為 window 對(duì)象,打印的 fullname 即是全局的。
var fullname = ‘David Jones’var obj ={fullname: ‘Colin Brown’,prop:{fullname:’Aurelio Deftch’,getFullname: function(){return this.fullname;}}}var test = obj.prop.getFullnameconsole.log(test()) // David Jonesobj.prop.getFullname() // ‘Aurelio Deftch’
18.解釋一下變量的提升
變量的提升是JavaScript的默認(rèn)行為,這意味著將所有變量聲明移動(dòng)到當(dāng)前作用域的頂部,并且可以在聲明之前使用變量。初始化不會(huì)被提升,提升僅作用于變量的聲明。
var x = 1console.log(x + '——' + y) // 1——undefinedvar y = 2
19.如何理解事件委托
這是一種讓父元素上的事件監(jiān)聽(tīng)器也影響子元素的技巧。通常,事件傳播(捕獲和冒泡)允許我們實(shí)現(xiàn)事件委托。冒泡意味著當(dāng)觸發(fā)子元素(目標(biāo))時(shí),也可以逐層觸發(fā)該子元素的父元素,直到它碰到DOM綁定的原始監(jiān)聽(tīng)器(當(dāng)前目標(biāo))。捕獲屬性將事件階段轉(zhuǎn)換為捕獲階段,讓事件下移到元素; 因此,觸發(fā)方向與冒泡階段相反。捕獲的默認(rèn)值為false。
22.什么是事件傳播?
當(dāng)事件發(fā)生在DOM元素上時(shí),該事件并不完全發(fā)生在那個(gè)元素上。在“冒泡階段”中,事件冒泡或向上傳播至父級(jí),祖父母,祖父母或父級(jí),直到到達(dá)window為止;而在“捕獲階段”中,事件從window開(kāi)始向下觸發(fā)元素 事件或event.target。
事件傳播有三個(gè)階段:
捕獲階段–事件從 window 開(kāi)始,然后向下到每個(gè)元素,直到到達(dá)目標(biāo)元素。
目標(biāo)階段–事件已達(dá)到目標(biāo)元素。
冒泡階段–事件從目標(biāo)元素冒泡,然后上升到每個(gè)元素,直到到達(dá) window。
21. event.preventDefault() 和 event.stopPropagation()方法之間有什么區(qū)別?
event.preventDefault() 方法可防止元素的默認(rèn)行為。如果在表單元素中使用,它將阻止其提交。如果在錨元素中使用,它將阻止其導(dǎo)航。如果在上下文菜單中使用,它將阻止其顯示或顯示。event.stopPropagation()方法用于阻止捕獲和冒泡階段中當(dāng)前事件的進(jìn)一步傳播。
22.原型繼承是如何工作的
JavaScript中有一個(gè)超級(jí)對(duì)象,所有對(duì)象都將從中繼承。'__ proto__'指向的對(duì)象的Prototype內(nèi)部屬性。原型(prototype )包含一個(gè)構(gòu)造函數(shù),使對(duì)象能夠從中創(chuàng)建實(shí)例。__proto__始終存在于對(duì)象中,并且分層指向它所屬的原型,直到null,這稱為原型鏈。
23.對(duì)象的 prototype(原型) 是什么?
原型就是對(duì)象的藍(lán)圖。如果它存在當(dāng)前對(duì)象中,則將其用作屬性和方法的回退。它是在對(duì)象之間共享屬性和功能的方法,這也是JavaScript實(shí)現(xiàn)繼承的核心。
const o = {};console.log(o.toString()); // logs [object Object]即使o對(duì)象中不存在o.toString方法,它也不會(huì)引發(fā)錯(cuò)誤,而是返回字符串[object Object]。
當(dāng)對(duì)象中不存在屬性時(shí),它將查看其原型,如果仍然不存在,則將其查找到原型的原型,依此類推,直到在原型鏈中找到具有相同屬性的屬性為止。
原型鏈的末尾是Object.prototype。
console.log(o.toString === Object.prototype.toString); // logs true24.map, filter, reduce 各自有什么作用?
map 作用是生成一個(gè)新數(shù)組,遍歷原數(shù)組,將每個(gè)元素拿出來(lái)做一些變換然后放入到新的數(shù)組中。
[1, 2, 3].map(v => v + 1) // -> [2, 3, 4]另外 map 的回調(diào)函數(shù)接受三個(gè)參數(shù),分別是當(dāng)前索引元素,索引,原數(shù)組['1','2','3'].map(parseInt)第一輪遍歷 parseInt('1', 0) -> 1第二輪遍歷 parseInt('2', 1) -> NaN第三輪遍歷 parseInt('3', 2) -> NaN
filter 的作用也是生成一個(gè)新數(shù)組,在遍歷數(shù)組的時(shí)候?qū)⒎祷刂禐?true 的元素放入新數(shù)組,我們可以利用這個(gè)函數(shù)刪除一些不需要的元素
let array = [1, 2, 4, 6]let newArray = array.filter(item => item!== 6)console.log(newArray) // [1, 2, 4]
reduce對(duì)數(shù)組中的每個(gè)元素執(zhí)行一個(gè)自定義的累計(jì)器,將其結(jié)果匯總為單個(gè)返回值
reduce的精華所在是將累計(jì)器逐個(gè)作用于數(shù)組成員上,把上一次輸出的值作為下一次輸入的值。
如果我們想實(shí)現(xiàn)一個(gè)功能將函數(shù)里的元素全部相加得到一個(gè)值,可能會(huì)這樣寫(xiě)代碼
const arr = [1, 2, 3]let total = 0for (let i = 0; i < arr.length; i++) {total += arr[i]}console.log(total) //6
但是如果我們使用 reduce 的話就可以將遍歷部分的代碼優(yōu)化為一行代碼
const arr = [1, 2, 3]const sum = arr.reduce((acc, current) =>acc + current, 0)console.log(sum)
?? 看完三件事
如果你覺(jué)得這篇內(nèi)容對(duì)你挺有啟發(fā),我想邀請(qǐng)你幫我三個(gè)小忙:
點(diǎn)贊,讓更多的人也能看到這篇內(nèi)容(收藏不點(diǎn)贊,都是耍流氓)。 關(guān)注公眾號(hào)「入坑互聯(lián)網(wǎng)」,不定期分享原創(chuàng)知識(shí)。 也看看其它文章
- END -
結(jié)伴同行前端路

