摘要:簡(jiǎn)單說(shuō)就是一個(gè)有一個(gè)函數(shù),這個(gè)函數(shù)執(zhí)行的返回值一定是一個(gè)對(duì)象,對(duì)象有兩個(gè)屬性標(biāo)記迭代是否結(jié)束,標(biāo)記這次迭代的結(jié)果值。
引言
遍歷對(duì)象是平常工作中很常見的一個(gè)操作,幾乎是日常操作,但是遍歷對(duì)象真的是一件很容易的事情么,顯然不是的。
常用的方式 for...infor (variable in object) {...}
這個(gè)是一個(gè)很常見的用法,相信每個(gè)人順手都可以寫出來(lái)。但是這里需要主要的是一段這個(gè)遍歷的定義
for...in語(yǔ)句以任意順序遍歷一個(gè)對(duì)象自有的、繼承的、可枚舉的、非Symbol的屬性。對(duì)于每個(gè)不同的屬性,語(yǔ)句都會(huì)被執(zhí)行。
一個(gè)一個(gè)詞摳吧。
對(duì)象自有的如果一個(gè)key是對(duì)象自有的那么一定可以用obj.hasOwnProperty(prop)的返回值來(lái)判斷
繼承的這個(gè)也很好理解,比如下面的例子
var parent = {a: 1}; function child() { this.b = "b"; } child.prototype = parent; var obj = new child();
此時(shí)由于obj的原型鏈繼承了parent,所以其實(shí)obj是有a屬性的。換句話說(shuō)for in會(huì)遍歷對(duì)象原型鏈上的屬性
可枚舉的什么是可枚舉的詳細(xì)的可以看一下這個(gè)鏈接
首先對(duì)象的屬性分為兩種,數(shù)據(jù)屬性如a["b"]=1,這個(gè)就是數(shù)據(jù)屬性,另一種就是訪問(wèn)器屬性,也就是我們用的getter。
這兩種屬性都有一個(gè)特性的[[Enumerable]],這個(gè)布爾值代表了這個(gè)屬性是否可以被枚舉。如果一個(gè)對(duì)象的屬性被設(shè)定為不可枚舉,那么for in并不可以遍歷到。可枚舉性可以用propertyIsEnumerable來(lái)判斷。
Symbol是什么這里不展開說(shuō)了不熟悉的建議看一下es6 symbol
symbol可以被用作給某個(gè)對(duì)象做私有屬性,而如果屬性值是symbol類型的那么for in也是無(wú)法遍歷的。
綜上可以明確的知道到底對(duì)象的哪些屬性可以用for in去遍歷出來(lái)了,坑點(diǎn)在基礎(chǔ)和可枚舉。數(shù)組遍歷我們會(huì)自然的去用for in,但是大家是否考慮過(guò),數(shù)組也是一個(gè)對(duì)象,為什么我們?cè)儆胒or in的時(shí)候不會(huì)把數(shù)組的長(zhǎng)度,length作為一個(gè)屬性遍歷到呢,原因也就是length屬性其實(shí)是一個(gè)不可枚舉屬性
Object.keys()Object.keys() 方法會(huì)返回一個(gè)由一個(gè)給定對(duì)象的自身可枚舉屬性組成的數(shù)組,數(shù)組中屬性名的排列順序和使用 for...in 循環(huán)遍歷該對(duì)象時(shí)返回的順序一致。
注意點(diǎn)這里和for in有一個(gè)很大的區(qū)別,就是這個(gè)返回的是對(duì)象自身可枚舉屬性組成的數(shù)組,不包含繼承
var parent = {a: 1}; function child() { this.b = "b"; } child.prototype = parent; var obj = new child(); Object.keys(obj); //["b"]Object.getOwnPropertyNames(obj)與Object.getOwnPropertySymbols(obj)
getOwnPropertyNames方法返回一個(gè)由指定對(duì)象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol值作為名稱的屬性)組成的數(shù)組。
getOwnPropertySymbols方法返回一個(gè)給定對(duì)象自身的所有 Symbol 屬性的數(shù)組。
關(guān)鍵詞,所有的,自身的。這兩個(gè)方法不受是否可枚舉屬性的限制,而且是只返回自身的,所以O(shè)bject.getOwnPropertyNames的返回值一定是包含了Object.keys的返回值
Reflect.ownKeys 方法返回一個(gè)由目標(biāo)對(duì)象自身的屬性鍵組成的數(shù)組。它的返回值等同于Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target))。
for...of接下來(lái)說(shuō)說(shuō)另一種遍歷的方案。for of 與for in 不同的就是for of是在可迭代對(duì)象(包括 Array,Map,Set,String,TypedArray,arguments 對(duì)象等等)上創(chuàng)建一個(gè)迭代循環(huán),調(diào)用自定義迭代鉤子,并為每個(gè)不同屬性的值執(zhí)行語(yǔ)句。下面還是進(jìn)入摳關(guān)鍵詞的階段
可迭代對(duì)象什么是可迭代對(duì)象?遵循有可迭代協(xié)議的對(duì)象成為可迭代對(duì)象,用人話說(shuō)就是一個(gè)對(duì)象如果有[Symbol.iterator],那么他就是可迭代對(duì)象。Symbol.iterator是es6提供了 1個(gè)內(nèi)置的 Symbol 值。
iterator簡(jiǎn)單說(shuō)就是一個(gè)有一個(gè)next函數(shù),這個(gè)函數(shù)執(zhí)行的返回值一定是一個(gè)對(duì)象,對(duì)象有兩個(gè)屬性done標(biāo)記迭代是否結(jié)束,value標(biāo)記這次迭代的結(jié)果值。
綜上所述也就是說(shuō)給你的要遍歷的對(duì)象增加一個(gè)Symbol.iterator就可以了
拓展運(yùn)算符除了上面說(shuō)的還想再補(bǔ)充一種遍歷的場(chǎng)景,對(duì)象的拓展運(yùn)算符,那么對(duì)象的拓展運(yùn)算符究竟是有哪些屬性可以被賦值。
自身的,可枚舉的??梢钥磧蓚€(gè)例子
var obj = {} Object.defineProperty(obj, "key", { enumerable: false, configurable: true, writable: true, value: "a" }); b = {...obj}; console.log(b); //{}
可以看到不可枚舉屬性在解構(gòu)賦值中是不可被賦值的。
var parent = {a: 1}; function child() { this.b = "b"; } child.prototype = parent; var obj = new child(); var b = {...obj}; console.log(b);//{b: "b"}
可以看到繼承的屬性在解構(gòu)賦值中是不可被賦值的。
總結(jié)對(duì)象的遍歷方法很多,但是要根據(jù)具體對(duì)象屬性的特征和應(yīng)用場(chǎng)景,還有兼容性來(lái)選擇最適合的遍歷方案。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109758.html
摘要:遍歷對(duì)象的屬性并沒(méi)有像中遍歷一個(gè)那么簡(jiǎn)單,主要原因有以下兩點(diǎn)在中對(duì)象的屬性分為可枚舉與不可枚舉之分他們是由屬性的的值決定的。 javascript遍歷對(duì)象的屬性并沒(méi)有像java中遍歷一個(gè)Map那么簡(jiǎn)單,主要原因有以下兩點(diǎn): 在javascript中對(duì)象的屬性分為可枚舉與不可枚舉之分,他們是由屬性的 enumerable 的值決定的??擅杜e性 決定了這個(gè)屬性是否可以被 for-in ...
摘要:日常開發(fā)中我們難免需要對(duì)數(shù)組和對(duì)象進(jìn)行遍歷,今天抽空來(lái)總結(jié)下遍歷數(shù)組和對(duì)象常用的方法。使用遍歷對(duì)象注只能遍歷出自身可枚舉的屬性,而不能遍歷出原型鏈上面的屬性。 日常開發(fā)中我們難免需要對(duì)數(shù)組和對(duì)象進(jìn)行遍歷,今天抽空來(lái)總結(jié)下遍歷數(shù)組和對(duì)象常用的方法。 Javascript遍歷數(shù)組總結(jié) 我們定義一個(gè)數(shù)組 var arr = [2,4,6]; 1.使用for循環(huán)遍歷 var lengt...
摘要:所以說(shuō)遍歷屬性時(shí),要考慮這兩個(gè)因素。開始遍歷先定義兩個(gè)類吧和,后者繼承前者。然后再聲明并初始化一個(gè)的實(shí)例。 原文鏈接 JavaScript 中遍歷對(duì)象的屬性 參考 JavaScript中的屬性:如何遍歷屬性《JavaScript 高級(jí)程序設(shè)計(jì)》 概述 遍歷 JavaScript 對(duì)象中的屬性沒(méi)有其他語(yǔ)言那么簡(jiǎn)單,因?yàn)閮蓚€(gè)因素會(huì)影響屬性的遍歷:對(duì)象屬性的屬性描述符 (property ...
摘要:接觸這么多年,第一次總結(jié)一下它的遍歷語(yǔ)法。而且你必須借助特定的結(jié)構(gòu)才能遍歷數(shù)據(jù)結(jié)構(gòu)。它的作用是遍歷對(duì)象的鍵名。建議僅在遍歷數(shù)組的時(shí)候使用。另一個(gè)優(yōu)點(diǎn)是,它可以遍歷任何部署了接口的數(shù)據(jù)結(jié)構(gòu),甚至是非的數(shù)據(jù)類型,即自己定義的數(shù)據(jù)結(jié)構(gòu)。 接觸JavaScript這么多年,第一次總結(jié)一下它的遍歷語(yǔ)法。以前我大部分時(shí)間都在老版本的JavaScript下寫代碼,所以大部分時(shí)間都是用for...in...
摘要:文章內(nèi)容分兩部分前半部分為迭代器模式概念后半部分為中迭代器上半部分開始迭代器模式提供一種方法順序訪問(wèn)一個(gè)聚合對(duì)象中的各個(gè)元素,而又不需要暴露該對(duì)象的內(nèi)部表示。下半部分開始的迭代器迭代器等同于遍歷器。執(zhí)行該函數(shù),會(huì)返回一個(gè)遍歷器對(duì)象。 showImg(https://segmentfault.com/img/bVbuyaZ?w=800&h=600); 文章內(nèi)容分兩部分: 前半部分為 迭...
摘要:總結(jié)中的循環(huán)遍歷定義一個(gè)數(shù)組和對(duì)象經(jīng)常用來(lái)遍歷數(shù)組元素遍歷值為數(shù)組元素索引用來(lái)遍歷數(shù)組元素第一個(gè)參數(shù)為數(shù)組元素,第二個(gè)參數(shù)為數(shù)組元素索引,第三個(gè)參數(shù)為數(shù)組本身可選沒(méi)有返回值用來(lái)遍歷數(shù)組元素第一個(gè)參數(shù)為數(shù)組元素,第二個(gè)參數(shù)為數(shù)組元素索引,第三 總結(jié)JavaScript中的循環(huán)遍歷 定義一個(gè)數(shù)組和對(duì)象 const arr = [a, b, c, d, e, f]; const obj = ...
閱讀 1856·2021-08-13 15:06
閱讀 3136·2021-08-05 10:02
閱讀 3438·2019-08-30 15:55
閱讀 2424·2019-08-30 13:46
閱讀 2529·2019-08-30 13:01
閱讀 1360·2019-08-29 17:17
閱讀 2854·2019-08-29 15:27
閱讀 1460·2019-08-29 11:12