摘要:對于每個枚舉的屬性,部分都會被執(zhí)行。被迭代枚舉的對象。三對數(shù)組的每個元素執(zhí)行一次提供的函數(shù)。沒有辦法終止會跳出循環(huán),除了拋出一個異常。當(dāng)?shù)竭_(dá)包含值的項(xiàng)時,整個數(shù)組的第一個項(xiàng)被移除了,這導(dǎo)致所有剩下的項(xiàng)前移了一個位置。
前言
初學(xué)JavaScript的時候,知道有各種for的時候,懵懵懂懂,也許是因?yàn)闆]有系統(tǒng)學(xué)習(xí)的緣故。現(xiàn)在我們把各種for都挨個辨明。
一、for創(chuàng)建一個循環(huán),包含三個可選表達(dá)式。三個可選表達(dá)式在圓括號中,由分號分隔。后跟一個循環(huán)中執(zhí)行的語句或塊語句。語法
initializationfor ([initialization]; [condition]; [final-expression]) statement
初始化語句。可寫表達(dá)式、賦值語句、變量聲明。
condition循環(huán)條件表達(dá)式。如果表達(dá)式結(jié)果為true,statement會被執(zhí)行。如果表達(dá)式結(jié)果為false,那么執(zhí)行流程跳到for語句結(jié)構(gòu)后面的第一條語句。不寫表達(dá)式,就是永遠(yuǎn)為true。
final-expression每次循環(huán)的最后都要執(zhí)行的表達(dá)式。執(zhí)行時機(jī)是在下一次condition的計算之前。
statement只要condition的結(jié)果為true就會被執(zhí)行的語句。多條語句使用塊語句({...})來包含。沒有語句執(zhí)行,使用空語句(;)。
示例我想輸出五個數(shù)字。
for (let i = 0; i < 5; i++) console.log(i); /* 0 1 2 3 4 */
另一種寫法輸出五個數(shù)字。可選的三個表達(dá)式,多行語句,需要使用{}包含起來。
for (let i = 0; ; i++) { if (i >= 5) break; console.log(i); } /* 0 1 2 3 4 */
注意,如果不寫條件表達(dá)式,就要確保循環(huán)體內(nèi)能夠跳出,防止死循環(huán)。break可以跳出循環(huán)。
二、for...in以任意順序遍歷一個對象的可枚舉屬性。對于每個枚舉的屬性,...部分都會被執(zhí)行。語法
variablefor (variable in object) {...}
每次迭代的時候,將對象的屬性名分配給變量。
object被迭代枚舉的對象。
示例我想輸出對象里所有的屬性和值。
let o = { a: 1, b: 2, c: 3 }; for (const v in o) { console.log(`o.${v} = ${o[v]}`); } /* o.a = 1 o.b = 2 o.c = 3 */
可以看見for...in把所有的可枚舉屬性都枚舉了出來,v的類型是String,所以訪問當(dāng)前遍歷到的屬性值使用了關(guān)聯(lián)數(shù)組o[v]的方式。
for...in在遍歷的時候,是以任意順序遍歷的。
let o = []; o[0] = 1; o["one"] = 2; o[2] = 3; for (const v in o) { console.log(`o[${v}] = ${o[v]}`); } /* o[0] = 1 o[2] = 3 o[one] = 2 */
因此當(dāng)遇到對迭代訪問順序很重要的數(shù)組時,最好用整數(shù)索引。
我想累加數(shù)組所有的成員。
Array.prototype.age = 97; let o = [1,2]; let sum = 0; for (const v in o) { sum += o[v]; console.log(`o[${v}] = ${o[v]}`); } console.log(`sum = ${sum}`); /* o[0] = 1 o[1] = 2 o[age] = 97 sum = 100 */
很顯然這里不符合我們的預(yù)期,因?yàn)?b>for...in循環(huán)語句將返回所有可枚舉屬性,包括非整數(shù)類型的名稱和繼承的那些。還會獲取到原型鏈上的可枚舉屬性。
我只想累加自身所有屬性。
Array.prototype.age = 97; let arr = [1, 2]; let sum = 0; for (const v in arr) { if (arr.hasOwnProperty(v)) { sum += arr[v]; } console.log(`arr[${v}] = ${arr[v]}`); } console.log(`sum = ${sum}`); /* o[0] = 1 o[1] = 2 o[age] = 97 sum = 3 */
如果你只要考慮對象本身的屬性,而不是它的原型,那么使用Object.getOwnPropertyNames()或執(zhí)行Object.prototype.hasOwnProperty()來確定某屬性是否是對象本身的屬性(也能使用propertyIsEnumerable)。
三、Array.prototype.forEach()對數(shù)組的每個元素執(zhí)行一次提供的函數(shù)。返回值為undefined。語法
callbackArray.forEach(callback[, thisArg])
為數(shù)組每個元素執(zhí)行的函數(shù),這個函數(shù)接受三個參數(shù)。
currentValue數(shù)組中正在處理的當(dāng)前元素值。
index數(shù)組中正在處理的當(dāng)前元素的索引。
arrayforEach()方法正在操作的數(shù)組。
thisArg可選參數(shù)。當(dāng)執(zhí)行回調(diào) 函數(shù)時用作this的值(參考對象)。
示例我想輸出所有元素。
function logArrayElements(element, index, array) { console.log(`a[${index}] = ${element}`); } [4, 2, 3].forEach(logArrayElements); /* a[0] = 4 a[1] = 2 a[2] = 3 */
forEcah()會跳過已經(jīng)刪除或者為初始化的項(xiàng)(但不包括那些值為undefined的項(xiàng),例如在稀疏數(shù)組上)。
function logArrayElements(element, index, array) { console.log(`a[${index}] = ${element}`); } [4, , 3].forEach(logArrayElements); [1, undefined, 3].forEach(logArrayElements); /* a[0] = 4 a[2] = 3 a[0] = 1 a[1] = undefined a[2] = 3 */
沒有辦法終止會跳出forEcah()循環(huán),除了拋出一個異常。
function logArrayElements(element, index, array) { console.log(`a[${index}] = ${element}`); break; } [1, 2, 3].forEach(logArrayElements); /* Uncaught SyntaxError: Illegal break statement at Array.forEach () at :5:11 */
使用return也無法中止循環(huán)。
使用thisArg,舉個勉強(qiáng)的例子。通過自定義的add()方法,計算所添加數(shù)組的和sum和成員數(shù)count。
function Counter() { this.sum = 0; this.count = 0; } Counter.prototype.add = function(array) { array.forEach(function(element) { this.sum += element; ++this.count; }, this); }; let obj = new Counter(); obj.add([1, 3, 5, 7]); console.log(obj.count); // 4 === (1+1+1+1) console.log(obj.sum); // 16 === (1+3+5+7) /* 4 16 */
注意:如果使用箭頭函數(shù)表達(dá)式傳入函數(shù)參數(shù),thisArg參數(shù)會被忽略,因?yàn)榧^函數(shù)在詞法上綁定了this值。
如果數(shù)組在迭代時被修改了,則其他元素會被跳過。
let words = ["one", "two", "three", "four"]; words.forEach(function(word) { console.log(word); if (word === "two") { words.shift(); } }); /* one two four */
當(dāng)?shù)竭_(dá)包含值"two"的項(xiàng)時,整個數(shù)組的第一個項(xiàng)被移除了,這導(dǎo)致所有剩下的項(xiàng)前移了一個位置。因?yàn)樵?b>"four"現(xiàn)在在數(shù)組更前的位置,"three"會被跳過。forEach()不會在迭代之前創(chuàng)建數(shù)組的副本。
四、for...offor...of語句在可以迭代的對象(Array、Map、Set、String、TypedArray、arguments對象等等)上創(chuàng)建一個迭代循環(huán),調(diào)用自定義迭代鉤子,并為每個不同屬性的值執(zhí)行語句。語法
variablefor (variable of iterable) { ... }
在每次迭代中,將不同屬性的值分配給變量。
iterable被迭代枚舉其屬性的對象。
示例 迭代Arraylet a = [10, 20, 30]; for (let v of a) { console.log(v); } /* 10 20 30 */迭代String
let s = "Tang"; for (let v of s) { console.log(v); } /* T a n g */迭代arguments
(function() { for (let v of arguments) { console.log(v); } } )(1, 2, 3); /* 1 2 3 */區(qū)別
無論是for...in還是for...of語句都是迭代一些東西。它們之間的主要區(qū)別在于它們的迭代方式。
for...in語句以原始插入順序迭代對象的可枚舉屬性。
for...of語句遍歷可迭代對象定義要迭代的數(shù)據(jù)。
以下示例顯示了與Array一起使用時,for...of循環(huán)和for...in循環(huán)之間的區(qū)別。
Object.prototype.objCustom = function() {}; Array.prototype.arrCustom = function() {}; let iterable = [3, 5, 7]; iterable.foo = "hello"; for (let i in iterable) { console.log(i); } /* 0 1 2 foo arrCustom objCustom */ for (let i in iterable) { if (iterable.hasOwnProperty(i)) { console.log(i); } } /* 0 1 2 foo */ for (let i of iterable) { console.log(i); } /* 3 5 7 */
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108069.html
摘要:四則運(yùn)算編譯器,雖然說功能很簡單,只能編譯四則運(yùn)算表達(dá)式。再復(fù)雜的編譯器再簡單的編譯器,功能上是差不多的,只是復(fù)雜的編譯器實(shí)現(xiàn)上會更困難。每一章都是理論與實(shí)踐結(jié)合的經(jīng)典,從計算機(jī)硬件知識到軟件體系,再到編譯原理和操作系統(tǒng)。 四則運(yùn)算編譯器,雖然說功能很簡單,只能編譯四則運(yùn)算表達(dá)式。但是編譯原理前端部分幾乎都有涉及,詞法分析,語法分析,還有代碼生成。 再復(fù)雜的編譯器、再簡單的編譯器,功能...
摘要:證書證書被稱為擴(kuò)展驗(yàn)證型證書,是因?yàn)樯暾堊C書不僅需要驗(yàn)證域名所有權(quán),按規(guī)定提交企業(yè)真實(shí)身份驗(yàn)證材料,還要求提供更加詳細(xì)的企業(yè)信息如具體營業(yè)地址等信息,并提供具有法律效力的證明文件如律師函等。以最大限度降低用戶訪問不安全網(wǎng)站的風(fēng)險。 什么是 HTTPS? HTTPS(超文本傳輸安全協(xié)議)是一種互聯(lián)網(wǎng)通信安全協(xié)議,它確保在用戶的計算機(jī)與網(wǎng)站終端服務(wù)器之間傳遞的數(shù)據(jù)的完整性和機(jī)密性。所以,為...
摘要:一個開放高效敏捷的物聯(lián)網(wǎng)應(yīng)用開發(fā)平臺,就此誕生,也被稱為全球最好用的物聯(lián)網(wǎng)操作系統(tǒng)。區(qū)塊鏈技術(shù)再加碼,物聯(lián)網(wǎng)生態(tài)持續(xù)精進(jìn)隨著區(qū)塊鏈技術(shù)的出現(xiàn)及持續(xù)升溫,如今區(qū)塊鏈已經(jīng)成為大眾廣泛關(guān)注的一個話題。 showImg(https://segmentfault.com/img/bV8bKH?w=2121&h=1414); 世界正在發(fā)生改變。 在無錫,中國第一個物聯(lián)網(wǎng)之城——鴻山小鎮(zhèn)已經(jīng)悄然誕生...
摘要:而且在這一版本里,微軟沒有提供圖形界面到的轉(zhuǎn)換。之父,在加入微軟之前是搞的。在發(fā)明了這后,直接就晉升為微軟的并且主導(dǎo)了的架構(gòu)設(shè)計跑遠(yuǎn)了,回來。通過遠(yuǎn)程在客戶端機(jī)器上運(yùn)行以下命令即可是客戶端機(jī)器的文件位置。 摘要: 相信有部分同學(xué)們會有這樣的體驗(yàn),在公有云上購買了Windows Server Version 1709數(shù)據(jù)中心版的虛擬機(jī),通過遠(yuǎn)程連接進(jìn)去之后,里面全是黑乎乎的一個命令行,其...
摘要:這也解答了我曾經(jīng)的一個疑問同樣的道理,在調(diào)用屬性的瞬間,也是使用先來實(shí)例化一個對象,所以那一瞬間他們的構(gòu)造函數(shù)以及原型對象是相同的,但也僅僅是那一瞬間。 經(jīng)常在國內(nèi)的各大網(wǎng)站博客上看到一句話,叫做JS中萬物皆對象,那是否真是如此? 那么,我們先來捋一捋JS中的數(shù)據(jù)類型,JS中的數(shù)據(jù)類型有下面幾種 Undefined Null Boolean Number String Symbol ...
閱讀 1084·2021-11-25 09:43
閱讀 707·2021-11-22 14:45
閱讀 3833·2021-09-30 09:48
閱讀 1073·2021-08-31 09:41
閱讀 1979·2019-08-30 13:52
閱讀 1988·2019-08-30 11:24
閱讀 1354·2019-08-30 11:07
閱讀 962·2019-08-29 12:15