|
|
|
|
|
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
允許你迭代對象的屬性,包括原型鏈中的屬性。
符號是一種始終唯一的原始數(shù)據(jù)類型。它們通常用作“私有”屬性,以避免在打算繼承時發(fā)生名稱沖突。并且由于它們旨在用作“私有”屬性,for...in
因此不會返回它們。
簡單來說,可枚舉屬性是enumerable
標(biāo)志設(shè)置為 true
的屬性,這是大多數(shù)屬性的默認(rèn)設(shè)置。這些是通過簡單賦值或通過屬性初始化器設(shè)置的屬性。
for (variable in object)
statement
variable
在每次迭代時,variable
會被賦值為不同的屬性名。
object
非 Symbol 類型的可枚舉屬性被迭代的對象。
備注:for...in
不應(yīng)該用于迭代一個關(guān)注索引順序的 Array
。
for ... in
是為遍歷對象屬性而構(gòu)建的,不建議與數(shù)組一起使用,數(shù)組可以用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 是一種基本數(shù)據(jù)類型(primitive data type)。Symbol()
函數(shù)會返回 symbol
類型的值,該類型具有靜態(tài)屬性和靜態(tài)方法。
每個從 Symbol()
返回的 symbol 值都是唯一的。一個 symbol 值能作為對象屬性的標(biāo)識符。參考如下示例:
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
對象等等)上創(chuàng)建一個迭代循環(huán),調(diào)用自定義迭代鉤子,并為每個不同屬性的值執(zhí)行語句。
for...of
語句迭代“可迭代對象”。想想 Array
和 String
,盡管有許多可迭代的對象類型。但是Object
默認(rèn)情況下不可迭代。
我們可以將for...of
視為對可迭代對象的值進行迭代。
為了使對象可迭代,它(或原型鏈中的對象)必須實現(xiàn)一個@@iterator
屬性,該屬性返回一個迭代器。迭代器對象是包含next
方法的對象,該方法返回序列中的下一項。有許多內(nèi)置的可迭代對象,例如Array
和String
。
for (variable of iterable) {
//statements
}
variable
在每次迭代中,將不同屬性的值分配給變量。
iterable
被迭代枚舉其屬性的對象。
一個示例看懂for...of和for...in的區(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); // 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
}
總結(jié)
for...in
和 for...of
還有更多細(xì)微差別,但你通??梢詫?code>for...in視為對對象屬性的迭代,而for...of
是對可迭代值的迭代。
無論是for...in
還是for...of
語句都是迭代一些東西。它們之間的主要區(qū)別在于它們的迭代方式。
for...in
語句以任意順序迭代對象的可枚舉屬性。
for...of
語句遍歷可迭代對象定義要迭代的數(shù)據(jù)。
相關(guān)文章