![](/img/trans.png)
[英]Checking whether something exists in a Javascript object with Jquery
[英]Checking whether something is iterable
在 MDN 文檔中: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
for...of
構造被描述為能夠迭代“可迭代”對象。 但是有沒有一種好的方法來決定一個對象是否可迭代?
我試圖找到數組、迭代器和生成器的通用屬性,但一直無法做到。
除了在 try 塊中執行for ... of
並檢查類型錯誤之外,是否有一種干凈的方法來做到這一點?
檢查可迭代性的正確方法如下:
function isIterable(obj) {
// checks for null and undefined
if (obj == null) {
return false;
}
return typeof obj[Symbol.iterator] === 'function';
}
為什么會這樣(深度迭代協議): https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Iteration_protocols
既然我們在談論 for..of,我假設,我們處於 ES6 心態。
另外,如果obj
是一個字符串,這個函數返回true
也不要感到驚訝,因為字符串會遍歷它們的字符。
最簡單的解決方案實際上是這樣的:
function isIterable (value) {
return Symbol.iterator in Object(value);
}
Object
會將任何不是對象的東西包裝成一個,即使原始值不是對象,也允許in
運算符工作。 null
和undefined
被轉換為空對象,因此不需要邊緣情況檢測,並且字符串被包裝成可迭代的 String 對象。
怎么這么啰嗦?
const isIterable = object =>
object != null && typeof object[Symbol.iterator] === 'function'
作為一個旁注,謹防關於迭代的定義。 如果你來自其他語言,你會期望你可以迭代的東西,比如for
循環是iterable 。 恐怕這里的情況並非如此, iterable意味着實現了迭代協議。
為了使事情更清楚,上面的所有示例都在此對象{a: 1, b: 2}
上返回false
,因為該對象未實現迭代協議。 所以你不能用for...of
迭代它for...of
但你仍然可以用for...in
。
因此,如果您想避免痛苦的錯誤,請通過如下所示重命名您的方法來使您的代碼更加具體:
/**
* @param variable
* @returns {boolean}
*/
const hasIterationProtocol = variable =>
variable !== null && Symbol.iterator in Object(variable);
如今,如前所述,要測試obj
是否可迭代,只需執行
obj != null && typeof obj[Symbol.iterator] === 'function'
for..of
結構是 ECMASCRipt 第 6 版語言規范草案的一部分。 所以它可以在最終版本之前改變。
在此草案中, 可迭代對象必須具有函數iterator
作為屬性。
您可以像這樣檢查對象是否可迭代:
function isIterable(obj){
if(obj === undefined || obj === null){
return false;
}
return obj.iterator !== undefined;
}
對於異步迭代器,您應該檢查“Symbol.asyncIterator”而不是“Symbol.iterator”:
async function* doSomething(i) {
yield 1;
yield 2;
}
let obj = doSomething();
console.log(typeof obj[Symbol.iterator] === 'function'); // false
console.log(typeof obj[Symbol.asyncIterator] === 'function'); // true
如果你想檢查一個變量是一個對象( {key: value}
)還是一個數組( [value, value]
),你可以這樣做:
const isArray = function (a) {
return Array.isArray(a);
};
const isObject = function (o) {
return o === Object(o) && !isArray(o) && typeof o !== 'function';
};
function isIterable(variable) {
return isArray(variable) || isObject(variable);
}
我正在尋找for ... in
的支票for ... in
並決定了以下內容。
isIterable (value) {
// add further checks here based on need.
return Object.keys(Object(value)).length > 0
}
對於任何可迭代且至少具有一個值的內容,這將返回true
。 因此,空字符串、空數組、空對象等將返回false
。 但是{a: 'x', b:'y'}
將返回true
。
就這樣
const isIterable = !!obj[Symbol.iterator]; // true | false
如果您問“是否foo
可迭代”,那么您可能來自一種語言(PHP、Python),其中該問題只有一個答案。 在現代 Javascript 中,有不同類型的可迭代對象。 因此,您必須根據要對變量執行的操作來檢查迭代的能力。
TL;DR:對於現代 Javascript 中的大多數用途, Boolean(foo.forEach)
會給你你想要的答案。
長答案:讓我們定義一些變量
someNumber = 42;
42
someArray = [1,2,3];
(3) [1, 2, 3]
someString = "Hello";
"Hello, world!"
someObject = {a:"A", b:"B"};
{a: "A", b: "B"}
現在讓我們用forEach
檢查它們:
someNumber.forEach;
undefined
someArray.forEach;
ƒ forEach() { [native code] }
someString.forEach;
undefined
someObject.forEach;
undefined
只有Array似乎可以用 forEach 迭代。
現在讓我們用for..in
檢查它們:
for (x in someNumber) { console.log(x); }
undefined
for (x in someArray) { console.log(x); }
VM20918:1 0
VM20918:1 1
VM20918:1 2
undefined
for (x in someString) { console.log(x); }
VM20945:1 0
VM20945:1 1
VM20945:1 2
VM20945:1 3
VM20945:1 4
undefined
for (x in someObject) { console.log(x); }
VM20972:1 a
VM20972:1 b
undefined
數組、字符串和對象似乎都可以用for..in
迭代。 盡管它沒有迭代,但 Number 沒有拋出錯誤。
現在讓我們用for..of
檢查它們:
for (x of someNumber) { console.log(x); }
VM21027:1 Uncaught TypeError: someNumber is not iterable
at <anonymous>:1:11
for (x of someArray) { console.log(x); }
VM21047:1 1
VM21047:1 2
VM21047:1 3
undefined
for (x of someString) { console.log(x); }
VM21065:1 H
VM21065:1 e
VM21065:1 l
VM21065:1 l
VM21065:1 o
undefined
for (x of someObject) { console.log(x); }
VM21085:1 Uncaught TypeError: someObject is not iterable
at <anonymous>:1:11
數組和字符串似乎可以用 for..of 迭代,但對象不是。 並且 Number 和 Object 都拋出了錯誤。
在現代的 ES6 Javascript 中,我看到forEach
使用頻率遠遠高於for..in
或for..of
。 但是 Javascript 開發人員必須意識到這三種方法之間的差異,以及每種方法的不同行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.