|
|
|
|
|
|
JavaScript 中有兩個非常相似的語句:for...in和for...of,雖然它們很容易混淆,但它們實際上完全不同。在本文中,我將介紹這兩種語句的用法以及每個語句的多個示例。
for...in
for...in是迭代對象的可枚舉屬性,我們通過下面的示例對此進行解釋:
const someObj = { someProp: 123 };
let otherObj = Object.create(someObj);
otherObj.otherProp = 456;
for (let key in otherObj) {
console.log(key);
}輸出
otherProp
someProp
如你所見,for...in迭代的是 someObj 對象的屬性:otherProp和someProp。
for...in語句遍歷所有“對象的非 Symbol 、可枚舉屬性”。那么這是什么意思?基本上,for...in允許你迭代對象的屬性,包括原型鏈中的屬性。
符號是一種始終唯一的原始數據類型。它們通常用作“私有”屬性,以避免在打算繼承時發生名稱沖突。并且由于它們旨在用作“私有”屬性,for...in因此不會返回它們。
簡單來說,可枚舉屬性是enumerable標志設置為 true 的屬性,這是大多數屬性的默認設置。這些是通過簡單賦值或通過屬性初始化器設置的屬性。
for (variable in object)
statement
variable
在每次迭代時,variable 會被賦值為不同的屬性名。
object
非 Symbol 類型的可枚舉屬性被迭代的對象。
備注:for...in不應該用于迭代一個關注索引順序的 Array。
for ... in是為遍歷對象屬性而構建的,不建議與數組一起使用,數組可以用Array.prototype.forEach()和for ... of。
Symbols 在 for...in 迭代中不可枚舉。參考如下示例:
var obj = {};
obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";
for (var i in obj) {
console.log(i); // logs "c" and "d"
}symbol 是一種基本數據類型(primitive data type)。Symbol() 函數會返回 symbol 類型的值,該類型具有靜態屬性和靜態方法。
每個從 Symbol() 返回的 symbol 值都是唯一的。一個 symbol 值能作為對象屬性的標識符。參考如下示例:
const symbol1 = Symbol();
const symbol2 = Symbol(42);
const symbol3 = Symbol('foo');
console.log(typeof symbol1);
// expected output: "symbol"
console.log(symbol2 === 42);
// expected output: false
console.log(symbol3.toString());
// expected output: "Symbol(foo)"
console.log(Symbol('foo') === Symbol('foo'));
// expected output: false
for...of
for...of是迭代“可迭代集合”,我們通過下面的示例對此進行解釋:
const primes = [2, 3, 5, 7];
for (let prime of primes) {
console.log(prime);
}
輸出
2
3
5
7
如你所見,for...of迭代的是primes對象的值。
for...of語句在可迭代對象(包括 Array,Map,Set,String,TypedArray,arguments 對象等等)上創建一個迭代循環,調用自定義迭代鉤子,并為每個不同屬性的值執行語句。
for...of語句迭代“可迭代對象”。想想 Array 和 String,盡管有許多可迭代的對象類型。但是Object默認情況下不可迭代。
我們可以將for...of視為對可迭代對象的值進行迭代。
為了使對象可迭代,它(或原型鏈中的對象)必須實現一個@@iterator屬性,該屬性返回一個迭代器。迭代器對象是包含next方法的對象,該方法返回序列中的下一項。有許多內置的可迭代對象,例如Array和String。
for (variable of iterable) {
//statements
}variable
在每次迭代中,將不同屬性的值分配給變量。
iterable
被迭代枚舉其屬性的對象。
一個示例看懂for...of和for...in的區別
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {};
let iterable = [3, 5, 7];
iterable.foo = 'hello';
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}總結
for...in 和 for...of 還有更多細微差別,但你通常可以將for...in視為對對象屬性的迭代,而for...of是對可迭代值的迭代。
無論是for...in還是for...of語句都是迭代一些東西。它們之間的主要區別在于它們的迭代方式。
for...in 語句以任意順序迭代對象的可枚舉屬性。
for...of 語句遍歷可迭代對象定義要迭代的數據。
相關文章
