久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

為什么 JavaScript 中的對(duì)象不可迭代?

Why are Objects not Iterable in JavaScript?(為什么 JavaScript 中的對(duì)象不可迭代?)
本文介紹了為什么 JavaScript 中的對(duì)象不可迭代?的處理方法,對(duì)大家解決問(wèn)題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧!

問(wèn)題描述

為什么對(duì)象默認(rèn)不可迭代?

我經(jīng)常看到與迭代對(duì)象相關(guān)的問(wèn)題,常見的解決方案是迭代對(duì)象的屬性并以這種方式訪問(wèn)??對(duì)象中的值.這似乎很常見,以至于我想知道為什么對(duì)象本身不可迭代.

類似 ES6 的語(yǔ)句 , HtmlCollectionarguments,它們不能轉(zhuǎn)換成數(shù)組.

例如:

var argumentsArray = Array.prototype.slice.call(arguments);

或與數(shù)組方法一起使用:

Array.prototype.forEach.call(nodeList, function (element) {}).

除了我上面的問(wèn)題,我很想看到一個(gè)關(guān)于如何將 {} 對(duì)象變成可迭代對(duì)象的工作示例,尤其是那些提到 [Symbol.iterator]. 這應(yīng)該允許這些新的 {} 可迭代對(duì)象"使用像 for...of 這樣的語(yǔ)句.另外,我想知道使對(duì)象可迭代是否允許將它們轉(zhuǎn)換為數(shù)組.

我嘗試了下面的代碼,但我得到一個(gè) TypeError: can't convert undefined to object.

var example = {a: {e: '一', f: '二'}, b: {g: '三'}, c: {h: '四', i: '五'}};//我希望能夠?qū)xample"對(duì)象使用for...of".//我還希望能夠?qū)⑹纠?對(duì)象轉(zhuǎn)換為數(shù)組.示例[Symbol.iterator] = function* (obj) {for (let key of Object.keys(obj)) {產(chǎn)量 [key, obj[key]];}};for (let [key, value] of example) { console.log(value);}//錯(cuò)誤console.log([...example]);//錯(cuò)誤

解決方案

我會(huì)試試這個(gè).請(qǐng)注意,我不隸屬于 ECMA,也無(wú)法了解他們的決策過(guò)程,因此我無(wú)法明確說(shuō)明為什么他們有或沒(méi)有做過(guò)任何事情.不過(guò),我會(huì)陳述我的假設(shè)并盡力而為.

1.為什么首先要添加 for...of 構(gòu)造?

JavaScript 已經(jīng)包含一個(gè) for...in 構(gòu)造,可用于迭代對(duì)象的屬性.但是,它并不是真正的 forEach 循環(huán),因?yàn)樗杜e了對(duì)象的所有屬性并且往往只能在可預(yù)測(cè)的情況下工作簡(jiǎn)單的案例.

它在更復(fù)雜的情況下(包括數(shù)組,它的使用往往是 對(duì)使用 for...in 和數(shù)組正確所需的保護(hù)措施感到沮喪或徹底混淆).您可以通過(guò)使用 hasOwnProperty (除其他外)來(lái)解決這個(gè)問(wèn)題,但這有點(diǎn)笨拙和不優(yōu)雅.

因此,我的假設(shè)是添加 for...of 構(gòu)造以解決與 for...in 構(gòu)造相關(guān)的缺陷,并提供更好的迭代事物時(shí)的實(shí)用性和靈活性.人們傾向于將 for...in 視為一個(gè) forEach 循環(huán),它通常可以應(yīng)用于任何集合并在任何可能的上下文中產(chǎn)生合理的結(jié)果,但事實(shí)并非如此.for...of 循環(huán)解決了這個(gè)問(wèn)題.

我還假設(shè)現(xiàn)有的 ES5 代碼在 ES6 下運(yùn)行并產(chǎn)生與在 ES5 下相同的結(jié)果很重要,因此不能對(duì) for... 的行為進(jìn)行重大更改.在 構(gòu)造.

<強(qiáng)>2.for...of 是如何工作的?

參考文檔對(duì)此部分很有用.具體來(lái)說(shuō),如果一個(gè)對(duì)象定義了 Symbol.iterator 屬性,則該對(duì)象被視為 iterable.

屬性定義應(yīng)該是一個(gè)函數(shù),它返回集合中的項(xiàng)目,one,by,one,并設(shè)置一個(gè)標(biāo)志,指示是否還有更多項(xiàng)目要獲取.為一些對(duì)象類型提供了預(yù)定義的實(shí)現(xiàn),使用for...of 簡(jiǎn)單地委托給迭代器函數(shù).

這種方法很有用,因?yàn)樗固峁┠约旱牡髯兊梅浅:?jiǎn)單.我可能會(huì)說(shuō)這種方法可能會(huì)帶來(lái)實(shí)際問(wèn)題,因?yàn)樗蕾囉诙x一個(gè)以前沒(méi)有的屬性,除了我可以說(shuō)的情況并非如此,因?yàn)槌悄愎室馊ふ宜駝t基本上會(huì)忽略新屬性(即它不會(huì)出現(xiàn)在 for...in 循環(huán)中作為鍵等).所以事實(shí)并非如此.

拋開實(shí)際的非問(wèn)題不談,以新的預(yù)定義屬性開始所有對(duì)象或隱含地說(shuō)每個(gè)對(duì)象都是一個(gè)集合"可能在概念上被認(rèn)為是有爭(zhēng)議的.

3.為什么對(duì)象不能iterable默認(rèn)使用for...of?

我的猜測(cè)是這是以下的組合:

  1. 默認(rèn)情況下使所有對(duì)象 iterable 可能被認(rèn)為是不可接受的,因?yàn)樗谝郧皼](méi)有屬性的地方添加了一個(gè)屬性,或者因?yàn)橐粋€(gè)對(duì)象(不一定)不是一個(gè)集合.正如 Felix 所說(shuō),迭代函數(shù)或正則表達(dá)式對(duì)象意味著什么"?
  2. 簡(jiǎn)單的對(duì)象已經(jīng)可以使用 for...in 進(jìn)行迭代了,目前尚不清楚內(nèi)置的迭代器實(shí)現(xiàn)與現(xiàn)有的 for... 相比有什么不同/更好. 行為.因此,即使 #1 是錯(cuò)誤的并且添加該屬性是可以接受的,它也可能不會(huì)被視為有用.
  3. 想要使他們的對(duì)象iterable 的用戶可以通過(guò)定義Symbol.iterator 屬性輕松地做到這一點(diǎn).
  4. ES6 規(guī)范還提供了 地圖 類型,默認(rèn)情況下 iterable,并且與使用普通對(duì)象作為 Map 相比還有一些其他的小優(yōu)勢(shì).

參考文檔中甚至還為#3 提供了一個(gè)示例:

var myIterable = {};myIterable[Symbol.iterator] = function* () {產(chǎn)量1;產(chǎn)量2;產(chǎn)量 3;};for (var value of myIterable) {控制臺(tái).log(值);}

鑒于對(duì)象可以很容易地制成 iterable,它們已經(jīng)可以使用 for...in 進(jìn)行迭代,而且對(duì)于什么是默認(rèn)值可能沒(méi)有明確的協(xié)議對(duì)象迭代器應(yīng)該做的(如果它所做的與 for...in 所做的有所不同),對(duì)象不是由 iterable默認(rèn).

請(qǐng)注意,您的示例代碼可以使用 for...in 重寫:

for (let levelOneKey in object) {console.log(levelOneKey);// 例子"console.log(object[levelOneKey]);//{"random":"nest","another":"thing"}var levelTwoObj = object[levelOneKey];for (let levelTwoKey in levelTwoObj ) {console.log(levelTwoKey);//隨機(jī)的"console.log(levelTwoObj[levelTwoKey]);//巢"}}

...或者您也可以通過(guò)執(zhí)行以下操作以您想要的方式使您的對(duì)象 iterable (或者您可以使 all 對(duì)象 iterable 通過(guò)分配給 Object.prototype[Symbol.iterator] 代替):

obj = {一個(gè):'1',b:{某事:'其他'},三:4,d:{嵌套:{nestedAgain:真}}};obj[Symbol.iterator] = function() {變量鍵 = [];var ref = 這個(gè);for (var key in this) {//注意:可以在這里做hasOwnProperty(),等等.鍵.push(鍵);}返回 {下一個(gè):函數(shù)(){if (this._keys && this._obj && this._index < this._keys.length) {var key = this._keys[this._index];this._index++;返回{鍵:鍵,值:this._obj [鍵],完成:假};} 別的 {返回{完成:真};}},_index: 0,_keys:鍵,_obj:參考};};

你可以在這里玩(至少在 Chrome 中):http://jsfiddle.net/rncr3ppz/5/

編輯

并且針對(duì)您更新的問(wèn)題,是的,可以使用 iterable 轉(zhuǎn)換為數(shù)組ES6 中的 US/docs/Web/JavaScript/Reference/Operators/Spread_operator" rel="noreferrer">擴(kuò)展運(yùn)算符.

但是,這似乎還沒(méi)有在 Chrome 中運(yùn)行,或者至少我無(wú)法讓它在我的 jsFiddle 中運(yùn)行.理論上它應(yīng)該很簡(jiǎn)單:

var 數(shù)組 = [...myIterable];

Why are objects not iterable by default?

I see questions all the time related to iterating objects, the common solution being to iterate over an object's properties and accessing the values within an object that way. This seems so common that it makes me wonder why objects themselves aren't iterable.

Statements like the ES6 for...of would be nice to use for objects by default. Because these features are only available for special "iterable objects" which don't include {} objects, we have to go through hoops to make this work for objects we want to use it for.

The for...of statement creates a loop Iterating over iterable objects (including Array, Map, Set, arguments object and so on)...

For example using an ES6 generator function:

var example = {a: {e: 'one', f: 'two'}, b: {g: 'three'}, c: {h: 'four', i: 'five'}};

function* entries(obj) {
   for (let key of Object.keys(obj)) {
     yield [key, obj[key]];
   }
}

for (let [key, value] of entries(example)) {
  console.log(key);
  console.log(value);
  for (let [key, value] of entries(value)) {
    console.log(key);
    console.log(value);
  }
}

The above properly logs data in the order I expect it to when I run the code in Firefox (which supports ES6):

By default, {} objects are not iterable, but why? Would the disadvantages outweigh the potential benefits of objects being iterable? What are the issues associated with this?

In addition, because {} objects are different from "Array-like" collections and "iterable objects" such as NodeList, HtmlCollection, and arguments, they can't be converted into Arrays.

For example:

var argumentsArray = Array.prototype.slice.call(arguments);

or be used with Array methods:

Array.prototype.forEach.call(nodeList, function (element) {}).

Besides the questions I have above, I would love to see a working example on how to make {} objects into iterables, especially from those who have mentioned the [Symbol.iterator]. This should allow these new {} "iterable objects" to use statements like for...of. Also, I wonder if making objects iterable allow them to be converted into Arrays.

I tried the below code, but I get a TypeError: can't convert undefined to object.

var example = {a: {e: 'one', f: 'two'}, b: {g: 'three'}, c: {h: 'four', i: 'five'}};

// I want to be able to use "for...of" for the "example" object.
// I also want to be able to convert the "example" object into an Array.
example[Symbol.iterator] = function* (obj) {
   for (let key of Object.keys(obj)) {
     yield [key, obj[key]];
   }
};

for (let [key, value] of example) { console.log(value); } // error
console.log([...example]); // error

解決方案

I'll give this a try. Note that I'm not affiliated with ECMA and have no visibility into their decision-making process, so I cannot definitively say why they have or have not done anything. However, I'll state my assumptions and take my best shot.

1. Why add a for...of construct in the first place?

JavaScript already includes a for...in construct that can be used to iterate the properties of an object. However, it's not really a forEach loop, as it enumerates all of the properties on an object and tends to only work predictably in simple cases.

It breaks down in more complex cases (including with arrays, where its use tends to be either discouraged or thoroughly obfuscated by the safeguards needed to for use for...in with an array correctly). You can work around that by using hasOwnProperty (among other things), but that's a bit clunky and inelegant.

So therefore my assumption is that the for...of construct is being added to address the deficiencies associated with the for...in construct, and provide greater utility and flexibility when iterating things. People tend to treat for...in as a forEach loop that can be generally applied to any collection and produce sane results in any possible context, but that's not what happens. The for...of loop fixes that.

I also assume that it's important for existing ES5 code to run under ES6 and produce the same result as it did under ES5, so breaking changes cannot be made, for instance, to the behavior of the for...in construct.

2. How does for...of work?

The reference documentation is useful for this part. Specifically, an object is considered iterable if it defines the Symbol.iterator property.

The property-definition should be a function that returns the items in the collection, one, by, one, and sets a flag indicating whether or not there are more items to fetch. Predefined implementations are provided for some object-types, and it's relatively clear that using for...of simply delegates to the iterator function.

This approach is useful, as it makes it very straightforward to provide your own iterators. I might say the approach could have presented practical issues due to its reliance upon defining a property where previously there was none, except from what I can tell that's not the case as the new property is essentially ignored unless you deliberately go looking for it (i.e. it will not present in for...in loops as a key, etc.). So that's not the case.

Practical non-issues aside, it may have been considered conceptually controversial to start all objects off with a new pre-defined property, or to implicitly say that "every object is a collection".

3. Why are objects not iterable using for...of by default?

My guess is that this is a combination of:

  1. Making all objects iterable by default may have been considered unacceptable because it adds a property where previously there was none, or because an object isn't (necessarily) a collection. As Felix notes, "what does it mean to iterate over a function or a regular expression object"?
  2. Simple objects can already be iterated using for...in, and it's not clear what a built-in iterator implementation could have done differently/better than the existing for...in behavior. So even if #1 is wrong and adding the property was acceptable, it may not have been seen as useful.
  3. Users who want to make their objects iterable can easily do so, by defining the Symbol.iterator property.
  4. The ES6 spec also provides a Map type, which is iterable by default and has some other small advantages over using a plain object as a Map.

There's even an example provided for #3 in the reference documentation:

var myIterable = {};
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};

for (var value of myIterable) {
    console.log(value);
}

Given that objects can easily be made iterable, that they can already be iterated using for...in, and that there's likely not clear agreement on what a default object iterator should do (if what it does is meant to be somehow different from what for...in does), it seems reasonable enough that objects were not made iterable by default.

Note that your example code can be rewritten using for...in:

for (let levelOneKey in object) {
    console.log(levelOneKey);         //  "example"
    console.log(object[levelOneKey]); // {"random":"nest","another":"thing"}

    var levelTwoObj = object[levelOneKey];
    for (let levelTwoKey in levelTwoObj ) {
        console.log(levelTwoKey);   // "random"
        console.log(levelTwoObj[levelTwoKey]); // "nest"
    }
}

...or you can also make your object iterable in the way you want by doing something like the following (or you can make all objects iterable by assigning to Object.prototype[Symbol.iterator] instead):

obj = { 
    a: '1', 
    b: { something: 'else' }, 
    c: 4, 
    d: { nested: { nestedAgain: true }}
};

obj[Symbol.iterator] = function() {
    var keys = [];
    var ref = this;
    for (var key in this) {
        //note:  can do hasOwnProperty() here, etc.
        keys.push(key);
    }

    return {
        next: function() {
            if (this._keys && this._obj && this._index < this._keys.length) {
                var key = this._keys[this._index];
                this._index++;
                return { key: key, value: this._obj[key], done: false };
            } else {
                return { done: true };
            }
        },
        _index: 0,
        _keys: keys,
        _obj: ref
    };
};

You can play with that here (in Chrome, at lease): http://jsfiddle.net/rncr3ppz/5/

Edit

And in response to your updated question, yes, it is possible to convert an iterable to an array, using the spread operator in ES6.

However, this doesn't seem to be working in Chrome yet, or at least I cannot get it to work in my jsFiddle. In theory it should be as simple as:

var array = [...myIterable];

這篇關(guān)于為什么 JavaScript 中的對(duì)象不可迭代?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來(lái)源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問(wèn)題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

discord.js v12: How do I await for messages in a DM channel?(discord.js v12:我如何等待 DM 頻道中的消息?)
how to make my bot mention the person who gave that bot command(如何讓我的機(jī)器人提及發(fā)出該機(jī)器人命令的人)
How to fix Must use import to load ES Module discord.js(如何修復(fù)必須使用導(dǎo)入來(lái)加載 ES 模塊 discord.js)
How to list all members from a specific server?(如何列出來(lái)自特定服務(wù)器的所有成員?)
Discord bot: Fix ‘FFMPEG not found’(Discord bot:修復(fù)“找不到 FFMPEG)
Welcome message when joining discord Server using discord.js(使用 discord.js 加入 discord 服務(wù)器時(shí)的歡迎消息)
主站蜘蛛池模板: 日韩精品一区二区三区高清免费 | 久久av一区二区三区 | 国产在线高清 | 成人国产精品免费观看 | 日韩视频在线观看 | 欧美激情综合色综合啪啪五月 | 天天干天天操 | 国产精品日韩欧美一区二区三区 | 91一区| 在线免费中文字幕 | 国产成人精品免费 | 一区日韩| 成人性视频在线 | 亚洲精品第一 | 日韩有码在线观看 | 国产a级黄色录像 | 成人黄色电影在线观看 | 久久久久久久久久久福利观看 | 国产成人精品一区二区三区视频 | 午夜精品视频在线观看 | 久久久久国产一区二区三区 | 毛片大全| 日韩欧美一区二区三区免费看 | 国内精品免费久久久久软件老师 | 精品91久久久 | 97精品超碰一区二区三区 | 成人综合视频在线观看 | 99riav国产一区二区三区 | 岛国在线免费观看 | 一区二区高清 | 国产精品日韩在线观看一区二区 | 神马久久春色视频 | 国产精品国色综合久久 | 一级一级毛片免费看 | 成人精品一区二区户外勾搭野战 | 欧美一区二区二区 | 久久这里只有精品首页 | 日韩一区二区三区精品 | av官网在线 | 成人免费淫片aa视频免费 | 成人国产精品久久久 |