- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
为什么默认情况下对象不可迭代?
我总是看到与迭代对象相关的问题,常见的解决方案是迭代对象的属性并以这种方式访问对象内的值。这似乎很常见,以至于我想知道为什么对象本身不可迭代。
类似 ES6 的语句 for...of
默认情况下用于对象会很好。因为这些功能仅适用于不包括 {}
的特殊“可迭代对象”。对象,我们必须通过箍来使这项工作适用于我们想要使用它的对象。
The for...of statement creates a loop Iterating over iterable objects (including Array, Map, Set, arguments object and so on)...
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);
}
}
{}
对象不可迭代,但为什么呢?缺点是否会超过对象可迭代的潜在好处?与此相关的问题是什么?
{}
对象不同于“类数组”集合和“可迭代对象”,例如
NodeList
,
HtmlCollection
, 和
arguments
,它们不能转换为数组。
var argumentsArray = Array.prototype.slice.call(arguments);
Array.prototype.forEach.call(nodeList, function (element) {})
.
{}
的工作示例。对象变成可迭代对象,尤其是那些提到 [Symbol.iterator]
的人. 这应该允许这些新的
{}
“可迭代对象”使用类似
for...of
的语句.另外,我想知道使对象可迭代是否允许将它们转换为数组。
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
最佳答案
我会试试这个。请注意,我不隶属于 ECMA,并且无法了解他们的决策过程,因此我无法明确说明他们为什么做了或没有做任何事情。但是,我会陈述我的假设并尽我所能。
1. 为什么要加for...of
首先构建?
JavaScript 已经包含一个 for...in
可用于迭代对象属性的构造。然而,它是 not really a forEach loop ,因为它枚举了一个对象的所有属性,并且往往只在简单的情况下才能可预测地工作。
它在更复杂的情况下会崩溃(包括使用数组,根据正确使用 for...in
与数组所需的保护措施,它的使用往往是 discouraged or thoroughly obfuscated)。您可以使用 hasOwnProperty
解决这个问题。 (除其他外),但这有点笨重和不优雅。
因此,我的假设是 for...of
正在添加构造以解决与 for...in
相关的缺陷构造,并在迭代事物时提供更大的实用性和灵活性。人们倾向于治疗for...in
作为 forEach
循环通常可以应用于任何集合并在任何可能的上下文中产生合理的结果,但事实并非如此。 for...of
循环解决了这个问题。
我还假设现有的 ES5 代码在 ES6 下运行并产生与在 ES5 下相同的结果很重要,因此不能对 for...in
的行为进行重大更改。构造。
2.如何for...of
工作?
reference documentation对这部分很有用。具体来说,一个对象被认为是 iterable
如果它定义了 Symbol.iterator
属性(property)。
属性定义应该是一个函数,它返回集合中的项目,一个,一个,一个,并设置一个标志,指示是否还有更多的项目要获取。为 some object-types 提供了预定义的实现,而且使用 for...of
比较清楚简单地委托(delegate)给迭代器函数。
这种方法很有用,因为它可以非常简单地提供您自己的迭代器。我可能会说这种方法可能会带来实际问题,因为它依赖于定义以前没有的属性,除非我可以说情况并非如此,因为除非您故意去寻找它,否则基本上忽略了新属性(即它不会作为键出现在 for...in
循环中,等等)。所以事实并非如此。
撇开实际的非问题不谈,以新的预定义属性开始所有对象,或隐含地说“每个对象都是一个集合”,这可能在概念上被认为是有争议的。
3.为什么对象不是iterable
使用 for...of
默认情况下?
我的猜测是,这是以下各项的组合:
iterable
默认情况下可能被认为是 Not Acceptable ,因为它添加了一个以前没有的属性,或者因为对象不是(必然)集合。正如 Felix 所指出的,“迭代一个函数或一个正则表达式对象是什么意思”? for...in
进行迭代,并且不清楚内置的迭代器实现可以比现有的 for...in
做得不同/更好。行为。因此,即使 #1 是错误的并且添加属性是可以接受的,它也可能不被视为有用。 iterable
可以很容易地做到这一点,通过定义 Symbol.iterator
属性(property)。 iterable
默认情况下,与使用普通对象作为 Map
相比,还有其他一些小优势。 . var myIterable = {};
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
};
for (var value of myIterable) {
console.log(value);
}
iterable
,它们已经可以使用
for...in
进行迭代,并且对于默认对象迭代器应该做什么(如果它所做的意味着与
for...in
所做的有所不同)可能没有明确的协议(protocol),似乎很合理,对象不是
iterable
默认情况下。
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"
}
}
iterable
以您想要的方式执行以下操作(或者您可以通过分配给
iterable
来创建所有对象
Object.prototype[Symbol.iterator]
):
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
};
};
iterable
到一个数组,使用
spread operator在 ES6 中。
var array = [...myIterable];
关于javascript - 为什么对象在 JavaScript 中不可迭代?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29886552/
我正在尝试将抓取的 xml 输出写入 json。由于项目不可序列化,抓取失败。 从这个问题来看,它建议您需要构建一个管道,未提供的答案超出了问题 SO scrapy serializer 的范围。 所
有没有一种方法可以通过重载函数来区分参数是在编译时可评估还是仅在运行时可评估? 假设我有以下功能: std::string lookup(int x) { return table::va
我正在使用 MVVM 模式编写一个应用程序。我通过将 View 的 DataContext 属性设置为 ViewModel 的实例来向 View 提供数据。一般来说,我只是从那里使用 Binding
对于一个项目,我正在使用带有简单 python module 的传感器收集多个红外命令。 . 我收到如下字节字符串: commando1= b'7g4770CQfwCTVT9bQDAzVEBMagGR
我有一个计算方法,可以在用户使用 Cartridge 作为我的商店框架结账时计算税费。 税 = 税 * 小数(str(settings.SHOP_DEFAULT_TAX_RATE)) 计算工作正常。然
我正在用 pygame 制作一个绘图程序,我想在其中为用户提供一个选项来保存程序的确切状态,然后在稍后重新加载它。在这一点上,我保存了我的全局字典的副本,然后遍历, pickle 每个对象。 pyga
在 C++11 之前,我可以使用它来使类不可复制: private: MyClass(const MyClass&); MyClass& operator=(const MyClass&); 使用 C
大家好 :) 我在我的 VC++ 项目中使用 1.5.4-all (2014-10-22)(适用于 x86 平台的 Microsoft Visual C++ 编译器 18.00.21005.1)。 我
我有一个 python 文件:analysis.py: def svm_analyze_AHE(file_name): # obtain abp file testdata = pd.
这个问题已经有答案了: How to serialize SqlAlchemy result to JSON? (37 个回答) 已关闭 4 年前。 我正在编写小查询来从 mysql 获取数据数据库,
我是 Python 初学者,我在 JSON 方面遇到了一些问题。在我正在使用的教程中有两个函数: def read_json(filename): data = [] if os.pa
我目前正在开发一个针对 iPad 的基于 HTML5 Canvas/JavaScript 的小型绘图应用程序。它在 Safari 中运行。到目前为止,除了一件事之外,一切都进展顺利。 如果我旋转设备,
以下代码无法使用 Visual Studio 2013 编译: #include struct X { X() = default; X(const X&) = delete;
嗨,我制作了一个文本分类分类器,我在其中使用了它,它返回一个数组,我想返回 jsonresponse,但最后一行代码给我错误 'array(['cycling'], dtype =object) 不可
我使用 Flask 和 Flask-Login 进行用户身份验证。 Flask-Sqlalchemy 将这些模型存储在 sqlite 数据库中: ROLE_USER = 0 ROLE_ADMIN =
如果您尝试发送不可 JSON 序列化的对象(列表、字典、整数等以外的任何对象),您会收到以下错误消息: "errorMessage": "Object of type set is not JSON
我在尝试 move std::vector 时遇到崩溃其中 T显然是不可 move 的(没有定义 move 构造函数/赋值运算符,它包含内部指针) 但为什么 vector 的 move 函数要调用 T
我尝试在用户成功登录后将 token 返回给他们,但不断收到以下错误: 类型错误:“字节”类型的对象不可 JSON 序列化 我该如何解决这个问题?这是我到目前为止的代码: if user:
我是一名优秀的程序员,十分优秀!