摘要:而的解析引擎遵循的是較老的第三版規(guī)范,屬性遍歷順序由屬性構(gòu)建的順序決定。將屬性設(shè)置為不可枚舉結(jié)語(yǔ)這篇文章希望能讓大家更加理解中的遍歷,寫(xiě)的不好多多見(jiàn)諒并指出
實(shí)例屬性和原型屬性
JavaScript中對(duì)象的屬性分為兩種: 數(shù)據(jù)屬性 和 訪問(wèn)器屬性 。
根據(jù)具體的上下文環(huán)境的不同,又可以將屬性分為: 原型屬性 和 實(shí)例屬性 。
原型屬性 是定義在對(duì)象的原型prototype 中的屬性,
實(shí)例屬性 一方面來(lái)自構(gòu)造的函數(shù)中,然后就是構(gòu)造函數(shù)實(shí)例化后添加的新屬性。
js的枚舉JavaScript中遍歷一個(gè)對(duì)象的屬性并不太簡(jiǎn)單,主要有兩個(gè)原因:
JavaScript中的對(duì)象通常都處在某個(gè)原型鏈中,它會(huì)從一個(gè)或多個(gè)的上層原型上繼承一些屬性
JavaScript中的屬性不光有值,它還有一些除了值以外的其他特性,其中一個(gè)影響屬性遍歷的特性就是Enumerable(一個(gè)屬性描述符) ,如果該值為 true ,則這個(gè)屬性是可枚舉的,否則反之
屬性描述符 主要有兩種形式:數(shù)據(jù)描述符和存取描述符。
使用Object.getOwnPropertyDescriptor 與 Object.getOwnPropertyDescriptors兩個(gè)方法獲取對(duì)象的屬性描述符。
var obj = { name: "10", _age: 25, get age(){ return this._age; }, set age(age){ if(age<1){ throw new Error("Age must be more than 0"); }else{ this._age = age; } } }; var des = Object.getOwnPropertyDescriptors(obj); console.log(des); /** * des: { * name: { * configurable: true, * enumerable: true, * value: "10", * writable: true, * __proto__: Object * }, * _age: { * configurable: true, * enumerable: true, * value: 25, * writable: true, * __proto__: Object * }, * age: { * configurable: true, * enumerable: true, * get: f age(), * set: f age(age), * __proto__: Object * }, * __proto__: Object * } */
該屬性的值(僅針對(duì)數(shù)據(jù)屬性描述符有效)
當(dāng)writable屬性設(shè)置為false時(shí),該屬性被稱為“不可寫(xiě)”。它不能被重新分配。
獲取該屬性的訪問(wèn)器函數(shù)(getter)。如果沒(méi)有訪問(wèn)器, 該值為undefined。(僅針對(duì)包含訪問(wèn)器或設(shè)置器的屬性描述有效)
獲取該屬性的設(shè)置器函數(shù)(setter)。 如果沒(méi)有設(shè)置器, 該值為undefined。(僅針對(duì)包含訪問(wèn)器或設(shè)置器的屬性描述有效)
configurable特性表示對(duì)象的屬性是否可以被刪除,以及除writable特性外的其他特性是否可以被修改。
enumerable定義了對(duì)象的屬性是否可以在 for...in 循環(huán)和 Object.keys() 中被枚舉。
name、_age擁有 "configurable"、"enumerable"、"value"、"writable"四個(gè)屬性描述符,統(tǒng)稱數(shù)據(jù)描述符
age擁有"configurable"、"enumerable"、"get"、"set"四個(gè)屬性描述符,統(tǒng)稱存取描述符
分類 | "configurable" | "enumerable" | "value" | "writable" | "get" | "set" |
---|---|---|---|---|---|---|
數(shù)據(jù)描述符 | yes | yes | yes | yes | no | no |
存取描述符 | yes | yes | no | no | yes | yes |
對(duì)象的屬性描述符,可以通過(guò)Object.defineProperty和Object.defineProperties來(lái)修改(configurable為true的條件下)
常用的遍歷方法 for...in...遍歷遍歷自身及原型鏈上所有可枚舉的屬性
使用 for...in 循環(huán)遍歷對(duì)象屬性時(shí)返回的屬性會(huì)因?yàn)楦鱾€(gè) 瀏覽器不同 導(dǎo)致對(duì)象屬性遍歷的順序有可能不是當(dāng)初構(gòu)建時(shí)的順序。
Chrome Opera 的 JavaScript 解析引擎遵循的是新版 ECMA-262 第五版規(guī)范。因此,使用 for-in 語(yǔ)句遍歷對(duì)象屬性時(shí)遍歷書(shū)序并非屬性構(gòu)建順序。而 IE6 IE7 IE8 Firefox Safari 的 JavaScript 解析引擎遵循的是較老的 ECMA-262 第三版規(guī)范,屬性遍歷順序由屬性構(gòu)建的順序決定。
for-in 語(yǔ)句無(wú)法保證遍歷順序,應(yīng)盡量避免編寫(xiě)依賴對(duì)象屬性順序的代碼。如果想順序遍歷一組數(shù)據(jù),請(qǐng)使用數(shù)組并使用 for 語(yǔ)句遍歷。
var Animal = function({name="none", age=3, weight=80}={}){ this.name = name; this.age = age; this.weight = weight; } Animal.prototype = { color: "red" } var dog = new Animal() // 將weight屬性設(shè)置為 不可枚舉 Object.defineProperty(dog, "weight", { enumerable: false }) for(let i in dog){ console.log(n); } //原型鏈上的color同樣被遍歷出來(lái)了,并且由于weight屬性被設(shè)置成了enumerable:false,所以不可被遍歷 //name //age //colorfor...of遍歷
一個(gè)數(shù)據(jù)結(jié)構(gòu)只要部署了Symbol.iterator屬性,就被視為具有 iterator 接口,就可以用for...of循環(huán)遍歷它的成員。也就是說(shuō),for...of循環(huán)內(nèi)部調(diào)用的是數(shù)據(jù)結(jié)構(gòu)的Symbol.iterator方法。
for...of循環(huán)可以使用的范圍包括數(shù)組、Set 和 Map 結(jié)構(gòu)、某些類似數(shù)組的對(duì)象(比如arguments對(duì)象、DOM NodeList 對(duì)象)、Generator 對(duì)象,以及字符串。
如果不太清楚iterator,請(qǐng)去看看阮一峰大神的這篇文章,里面關(guān)于for...of以及iterator都講的非常詳細(xì)!
其實(shí)for...of和for...in都是迭代一些東西,它們之間的主要區(qū)別在于它們的迭代方式。
for...in語(yǔ)句以原始插入順序迭代對(duì)象的可枚舉屬性。
for...of 語(yǔ)句遍歷可迭代對(duì)象定義要迭代的數(shù)據(jù)。
請(qǐng)仔細(xì)看以下實(shí)例,理解其中的區(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 }
Object.prototype.objCustom = function() {}; Array.prototype.arrCustom = function() {}; let iterable = [3, 5, 7]; iterable.foo = "hello";
在這段代碼里面,由于繼承和原型鏈,對(duì)象iterable繼承屬性objCustom和arrCustom。
for (let i in iterable) { console.log(i); // 0, 1, 2, "foo", "arrCustom", "objCustom" }
在這段代碼里面,此循環(huán)僅以原始插入順序記錄iterable 對(duì)象的可枚舉屬性。它不記錄數(shù)組元素3, 5, 7 或hello,因?yàn)檫@些不是枚舉屬性。但是它記錄了數(shù)組索引以及arrCustom和objCustom(為何記錄arrCustom和objCustom在本文for...in里面有講過(guò))。
for (let i in iterable) { if (iterable.hasOwnProperty(i)) { console.log(i); // 0, 1, 2, "foo" } }
hasOwnProperty()用來(lái)檢查找到的枚舉屬性是不是對(duì)象自己的(即是不是繼承的)
for (let i of iterable) { console.log(i); // 3, 5, 7 }
該循環(huán)迭代并記錄iterable作為可迭代對(duì)象定義的迭代值,這些是數(shù)組元素 3, 5, 7,而不是任何對(duì)象的屬性。
Object.keys遍歷Object.keys() 方法會(huì)返回一個(gè)由一個(gè)給定對(duì)象的自身可枚舉屬性組成的數(shù)組,數(shù)組中屬性名的排列順序和使用 for...in 循環(huán)遍歷該對(duì)象時(shí)返回的順序一致 (兩者的主要區(qū)別是 一個(gè) for-in 循環(huán)還會(huì)枚舉其原型鏈上的屬性)。
Object.getOwnPropertyNames()遍歷Object.getOwnPropertyNames()方法返回一個(gè)由指定對(duì)象的所有自身屬性的屬性名(包括不可枚舉屬性但不包括Symbol值作為名稱的屬性)組成的數(shù)組,此方法不會(huì)獲取原型鏈上的屬性。
var Animal = function({name="", age=1, weight=70}={}){ this.name = name; this.age = age; this.weight = weight; } Animal.prototype = { type: "Animal" } var dog = new Animal() // 將height屬性設(shè)置為 不可枚舉 Object.defineProperty(dog, "weight", { enumerable: false }) var keys = Object.getOwnPropertyNames(dog); console.log(keys) // ["name", "age", "weight"]結(jié)語(yǔ)
這篇文章希望能讓大家更加理解js中的遍歷,寫(xiě)的不好多多見(jiàn)諒并指出!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/94110.html
摘要:從而也引出了所謂的深淺復(fù)制問(wèn)題。附注對(duì)于淺復(fù)制,其實(shí)還有其他的實(shí)現(xiàn)方式,比如數(shù)組中和方法,對(duì)于這些還是希望大家自己了解,本本主要針對(duì)深淺復(fù)制的實(shí)現(xiàn)原理進(jìn)行解析。 前言 在之前寫(xiě)繼承的過(guò)程談到了深淺復(fù)制的問(wèn)題,因?yàn)橛凶x者反映到需要解析,趁今天周末寫(xiě)一篇解析,今天的主體相對(duì)之前來(lái)說(shuō)理解難度低一些,篇幅可能也比較短,諸君按需閱讀即可。 從兩種數(shù)據(jù)類型說(shuō)起 在js中,變量的類型可以大致分成兩種...
摘要:和的作用一樣,區(qū)別在于寫(xiě)法語(yǔ)法對(duì)象對(duì)象作用判斷對(duì)象是否在對(duì)象的原型鏈上語(yǔ)法對(duì)象構(gòu)造函數(shù)作用判斷構(gòu)造函數(shù)的屬性是否在對(duì)象的原型鏈上,如果在,就返回屬性是否可枚舉用于檢查給定的屬性是否能夠使用語(yǔ)句。 ## javascript對(duì)象原型成員詳解 ## ECMAScript 中的對(duì)象就是一組數(shù)據(jù)和功能的集合,對(duì)象可以通過(guò) new 操作符后跟要?jiǎng)?chuàng)建的對(duì)象名稱來(lái)...
摘要:和數(shù)組遍歷方法詳解在中常用的種數(shù)組遍歷方法原始的循環(huán)語(yǔ)句數(shù)組對(duì)象內(nèi)置方法數(shù)組對(duì)象內(nèi)置方法數(shù)組對(duì)象內(nèi)置方法數(shù)組對(duì)象內(nèi)置方法數(shù)組對(duì)象內(nèi)置方法數(shù)組對(duì)象內(nèi)置方法數(shù)組對(duì)象內(nèi)置方法數(shù)組對(duì)象內(nèi)置方法循環(huán)語(yǔ)句中新增加了一種循環(huán)語(yǔ)句三種數(shù)組循環(huán)示例如下原始循 ES5和ES6數(shù)組遍歷方法詳解 在ES5中常用的10種數(shù)組遍歷方法: 1、原始的for循環(huán)語(yǔ)句2、Array.prototype.forEach數(shù)...
摘要:創(chuàng)建數(shù)組數(shù)組字面量數(shù)組構(gòu)造函數(shù)參數(shù)為數(shù)組建議使用數(shù)組字面量方式,性能好,代碼少,簡(jiǎn)潔,畢竟代碼少。數(shù)組判斷方法用來(lái)判斷某個(gè)值是否為。的這是最簡(jiǎn)潔最直接的遍歷數(shù)組元素的語(yǔ)法。把數(shù)組轉(zhuǎn)換為本地?cái)?shù)組,并返回結(jié)果。 前端學(xué)習(xí):前端教程&開(kāi)發(fā)模塊化/規(guī)范化/工程化/優(yōu)化&工具/調(diào)試&值得關(guān)注的博客/Git&面試-前端資源匯總 歡迎提issues斧正:數(shù)組&數(shù)組方法使用詳解 Array對(duì)象 之前一...
摘要:個(gè)人前端文章整理從最開(kāi)始萌生寫(xiě)文章的想法,到著手開(kāi)始寫(xiě),再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會(huì)繼更新,現(xiàn)將已經(jīng)寫(xiě)好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開(kāi)始萌生寫(xiě)文章的想法,到著手...
閱讀 2144·2021-11-15 17:57
閱讀 839·2021-11-11 16:54
閱讀 2685·2021-09-27 13:58
閱讀 4520·2021-09-06 15:00
閱讀 1042·2021-09-04 16:45
閱讀 3574·2019-08-30 15:56
閱讀 1838·2019-08-30 15:53
閱讀 1764·2019-08-30 14:12