欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS中for...in?和?for...of?的區(qū)別解析

 更新時(shí)間:2024年03月27日 14:34:55   作者:fighting?~  
for?…?in?用于迭代對象的可枚舉字符串屬性,包括自身屬性和繼承的屬性,但不會遍歷對象的原型鏈上的?非可枚舉屬性,以及對象的方法,這篇文章主要介紹了JS中for...in?和?for...of?的區(qū)別,需要的朋友可以參考下

1. 迭代的對象不同

  • for … in 用于迭代對象的可枚舉字符串屬性,包括自身屬性繼承的屬性,但不會遍歷對象的原型鏈上的 非可枚舉屬性,以及對象的方法。

從內(nèi)置構(gòu)造函數(shù)(如 Array 和 Object)創(chuàng)建的對象會從 Array.prototype 和 Object.prototype 繼承不可枚舉屬性,例如 Array 的 indexOf() 方法或 Object 的 toString() 方法,它們在 for…in 循環(huán)中不會被訪問到。

  • for … of 用于迭代可迭代對象定義的要進(jìn)行迭代的值。可迭代對象 包括 數(shù)組、字符串、Set、Map等,還包括 arguments 對象。它遍歷的是可迭代對象的迭代器(Iterator)返回的值或鍵值對,而不能直接用于普通的對象。

當(dāng) for…of 循環(huán)迭代一個(gè)可迭代對象時(shí),它首先調(diào)用可迭代對象的 @@iterator 方法,該方法返回一個(gè)迭代器,然后重復(fù)調(diào)用生成器的 next() 方法,以生成要分配給 每次循環(huán)迭代的 可迭代對象 的值的序列。

注意: 每次迭代都會創(chuàng)建一個(gè)新的變量。在循環(huán)體內(nèi)部重新賦值變量不會影響可迭代對象的原始值。

要成為可迭代對象,必須要有一個(gè)迭代器 @@iterator方法,也就是說這個(gè)對象必須有一個(gè)鍵為@@iterator的屬性,通過常量 Symbol.iterator 訪問這個(gè)屬性,并返回一個(gè)迭代器對象

迭代器對象包含一個(gè) next() 方法,無參數(shù)或者接受一個(gè)參數(shù)的函數(shù),并返回符合 IteratorResult 接口的對象。
next() 方法會返回一個(gè)具有 valuedone 屬性的對象。

  • value 表示當(dāng)前迭代的值。如果迭代器已經(jīng)到達(dá)末尾,那么 value 的值通常為 undefined,但這并不是必然的,具體取決于迭代器的實(shí)現(xiàn)。
  • done 是一個(gè)布爾值,表示迭代是否已完成。迭代器是否已完成遍歷。當(dāng)遍歷結(jié)束時(shí),done 為 true,否則為 false。

實(shí)際上,兩者都不是嚴(yán)格要求的;如果返回沒有任何屬性的對象,則實(shí)際上等價(jià)于 { done: false, value: undefined }。

const obj = {
  a: 1,
  b: { h:123 },
};
//定義在自身的屬性
Object.defineProperty(obj, 'c', {
  value: 3,
});
//定義在自身的屬性
Object.defineProperty(obj, 'd', {
  value: 4,
  enumerable: true,//是否可枚舉,默認(rèn)false不可枚舉
});
//定義在原型上的屬性
Object.prototype.e=5;
for (let key in obj) {
  console.log(key); // 輸出 'a' 、 'b'、 'd'、'e',但不會輸出 'c'、'h'
}
console.log(Object.keys(obj)); // 輸出 ['a', 'b','d'],不包括 'c'、'e'、'h'
console.log(Object.getOwnPropertyNames(obj)); // 輸出 ['a', 'b', 'c','d'],包括 'c', 但不包括'e'、'h'
擴(kuò)展:

Object.keys 會返回一個(gè)包含所有可枚舉自有字符串屬性的數(shù)組,
Object.getOwnPropertyNames 則會包含所有屬性,包括不可枚舉的。
Object.getOwnPropertyDescriptor(obj, prop)靜態(tài)方法返回一個(gè)對象,該對象描述給定對象上特定屬性(即直接存在于對象上而不在對象的原型鏈中的屬性)的配置。

obj
要查找其屬性的對象。
prop
要檢索其描述的屬性的名稱或 Symbol。
返回值
如果指定的屬性存在于對象上,則返回其屬性描述符,否則返回 undefined。
// 對象本身的屬性的屬性描述符
const desc = Object.getOwnPropertyDescriptor(obj, "c");
console.log(desc);
// {
//	value: 3, 
// 	writable: false,
//	enumerable: false, 
// 	configurable: false
// }
// 對象原型上的屬性的屬性描述符
const desc1 = Object.getOwnPropertyDescriptor(Object.prototype, "e");
console.log(desc1);
//{
//	value: 5, 
//	writable: true, 
//	enumerable: true, 
//	configurable: true
// }

屬性描述符

  • value
與屬性關(guān)聯(lián)的值(僅限數(shù)據(jù)描述符)。
  • writable :是否可更改
當(dāng)且僅當(dāng)與屬性關(guān)聯(lián)的值可以更改時(shí),為 true(僅限數(shù)據(jù)描述符)。
  • enumerable : 是否可枚舉
當(dāng)且僅當(dāng)此屬性在相應(yīng)對象的屬性枚舉中出現(xiàn)時(shí),為 true。
  • configurable :是否可刪除
當(dāng)且僅當(dāng)此屬性描述符的類型可以更改且該屬性可以從相應(yīng)對象中刪除時(shí),為 true。

在迭代 Array 時(shí),for…of 循環(huán)和 for…in 循環(huán)之間的區(qū)別。

Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {};
const iterable = [3, 5, 7];
iterable.foo = "hello";
for (const i in iterable) {
  console.log(i);
}
// "0"、"1"、"2"、"foo"、"arrCustom"、"objCustom"
for (const i in iterable) {
  if (Object.hasOwn(iterable, i)) {
    console.log(i);
  }
}
// "0" "1" "2" "foo"
for (const i of iterable) {
  console.log(i);
}
// 3 5 7

使用 Object.hasOwn() 來檢查找到的可枚舉屬性是否為對象的自有屬性,即非繼承屬性。

const arr=['A','B', ,'D', ,'F'];
  for(const key in arr){
    console.log(key); //0,1,3,5
  }
  for(const item of arr){
    console.log(item); // A,B,undefined,D,undefined,F
  }

for…in 使用屬性枚舉而不是數(shù)組的迭代器。在稀疏數(shù)組中,for…of 會訪問空槽,但 for…in 不會訪問空槽。

2. 遍歷順序

  • for … in 循環(huán)遍歷對象屬性時(shí),遍歷的順序是不確定的,因?yàn)閷ο髮傩詻]有固定的順序。

根據(jù)現(xiàn)代 ECMAScript 規(guī)范的定義,遍歷的順序是一致且可預(yù)測的。在原型鏈的每個(gè)組件中,所有非負(fù)整數(shù)鍵(可以作為數(shù)組索引)將首先按值升序遍歷,然后是其他字符串鍵按屬性創(chuàng)建的先后順序升序遍歷。

  • for … of 循環(huán)遍歷可迭代對象時(shí),遍歷的順序是按照對象的迭代器定義的順序進(jìn)行的。

3. 可迭代性要求

  • for … in 循環(huán)不需要對象滿足可迭代性要求。
  • for … of 循環(huán)要求被遍歷的對象必須是可迭代對象(實(shí)現(xiàn)了迭代器接口)。如果對象沒有迭代器接口,嘗試使用 for … of 循環(huán)會拋出錯(cuò)誤。

總的來說:

  • for…in 循環(huán)用于迭代對象的可枚舉字符串屬性,包括自身屬性繼承的屬性,
  • for…of 循環(huán)用于迭代可迭代對象定義的要進(jìn)行迭代的值。

到此這篇關(guān)于JS中for...in 和 for...of 的區(qū)別的文章就介紹到這了,更多相關(guān)js for...in 和 for...of 區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論