1.for in

for...in语句以任意顺序遍历一个对象的可枚举性。对于每个不同的属性,语句都会被执行。

语法

for (variable in object) {...}
variable
在每次迭代时,将不同的属性名分配给变量
object
被迭代枚举其属性的对象。

描述

for...in 循环只遍历可枚举属性。像 ArrayObject使用内置构造函数所创建的对象都会继承自Object.prototypeString.prototype的不可枚举属性,例如 String 的 indexOf()  方法或 ObjecttoString()方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。

删除,添加或者修改属性

for...in 循环以任意序迭代一个对象的属性。如果一个属性在一次迭代中被修改,在稍后被访问,其在循环中的值是其在稍后时间的值。一个在被访问之前已经被删除的属性将不会在之后被访问。在迭代进行时被添加到对象的属性,可能在之后的迭代被访问,也可能被忽略。通常,在迭代过程中最好不要在对象上进行添加、修改或者删除属性的操作,除非是对当前正在被访问的属性。这里并不保证是否一个被添加的属性在迭代过程中会被访问到,不保证一个修改后的属性(除非是正在被访问的)会在修改前或者修改后被访问,不保证一个被删除的属性将会在它被删除之前被访问。

数组迭代和 for...in

数组索引只是具有整数名称的枚举属性,并且与通用对象属性相同。不能保证for ... in将以任何特定的顺序返回索引。for ... in循环语句将返回所有可枚举属性,包括非整数类型的名称和继承的那些。

因为迭代的顺序是依赖于执行环境的,所以数组遍历不一定按次序访问元素。因此当迭代访问顺序很重要的数组时,最好用整数索引去进行for循环(或者使用 Array.prototype.forEach()for...of 循环)。

仅迭代自身的属性

如果你只要考虑对象本身的属性,而不是它的原型,那么使用 getOwnPropertyNames() 或执行 hasOwnProperty() 来确定某属性是否是对象本身的属性(也能使用propertyIsEnumerable)。或者,如果你知道不会有任何外部代码干扰,您可以使用检查方法扩展内置原型。

示例

下面的函数接受一个对象作为参数。被调用时迭代传入对象的所有可枚举属性然后返回一个所有属性名和其对应值的字符串。

var obj = {a:1, b:2, c:3};

for (var prop in obj) {
console.log("obj." + prop + " = " + obj[prop]);
} // Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

2.for each...in

使用一个变量迭代一个对象的所有属性值,对于每一个属性值,有一个指定的语句块被执行.

语法

for each (variable in object) {
statement
}
variable
用来遍历属性值的变量,前面的var关键字是可选的.该变量是函数的局部变量而不是语句块的局部变量.
object
该对象的属性值会被遍历.
statement
遍历属性值时执行的语句. 如果想要执行多条语句, 请用({ ... }) 将多条语句括住.

描述

一些对象的内置属性是无法被遍历到的,包括所有的内置方法,例如String对象的indexOf方法.不过,大部分的用户自定义属性都是可遍历的.

示例

警告:永远不要使用for each...in语句遍历数组,仅用来遍历常规对象

下面的代码片段演示如何遍历一个对象的属性值, 并计算它们的和:

var sum = 0;
var obj = {prop1: 5, prop2: 13, prop3: 8}; for each (var item in obj) {
sum += item;
} print(sum); // 输出"26",也就是5+13+8的值

 3.for of

for...of语句在可迭代对象(包括 ArrayMapSetStringTypedArrayarguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

语法

for (variable of iterable){

//statements

}

variable
在每次迭代中,将不同属性的值分配给变量。

iterable
被迭代枚举其属性的对象。

示例

迭代Array


let iterable = [10, 20, 30];

for (let value of iterable) {
value += 1;
console.log(value);
}
// 11
// 21
// 31

for...offor...in的区别

无论是for...in还是for...of语句都是迭代一些东西。它们之间的主要区别在于它们的迭代方式。

for...in 语句以原始插入顺序迭代对象的可枚举属性

for...of 语句遍历可迭代对象定义要迭代的数据。

以下示例显示了与Array一起使用时,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
}
Object.prototype.objCustom = function() {};
Array.prototype.arrCustom = function() {}; let iterable = [3, 5, 7];
iterable.foo = 'hello';

每个对象将继承objCustom属性,并且作为Array的每个对象将继承arrCustom属性,因为将这些属性添加到Object.prototypeArray.prototype。由于继承和原型链,对象iterable继承属性objCustomarrCustom

for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}

此循环仅以原始插入顺序记录iterable 对象的可枚举属性。它不记录数组元素357 或hello,因为这些不是枚举属性。但是它记录了数组索引以及arrCustomobjCustom。如果你不知道为什么这些属性被迭代,array iteration and for...in中有更多解释。

for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}

这个循环类似于第一个,但是它使用hasOwnProperty() 来检查,如果找到的枚举属性是对象自己的(不是继承的)。如果是,该属性被记录。记录的属性是012foo,因为它们是自身的属性(不是继承的)。属性arrCustomobjCustom不会被记录,因为它们是继承的

for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}

该循环迭代并记录iterable作为可迭代对象定义的迭代值,这些是数组元素 357,而不是任何对象的属性

for ...in 、for each ...in、 for...of(https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/for...of)的更多相关文章

  1. 如何从https://developer.mozilla.org上查询对象的属性、方法、事件使用说明和示例

    在https://developer.mozilla.org搜索要在前面加上指令 搜索之后点进去 进入之后就是这样的 在页面左边你可以选择自己要查询的对象 里面就是会有属性.方法.事件使用说明和示例.

  2. js变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级

    原文出自:http://www.cnblogs.com/xxcanghai/p/5189353.html作者:小小沧海 题目如下: function Foo() { getName = functio ...

  3. doctype声明、浏览器的标准、怪异等模式

    doctype 标准(严格)模式(Standards Mode).怪异(混杂)模式(Quirks Mode),如何触发,区分他们有何意义? 触发标准模式 1.加DOCTYPE声明,比如:<!DO ...

  4. Ajax跨域、Json跨域、Socket跨域和Canvas跨域等同源策略限制的解决方法

    同源是指同样的协议.域名.port,三者都同样才属于同域.不符合上述定义的请求,则称为跨域. 相信每一个开发者都曾遇到过跨域请求的情况,尽管情况不一样,但问题的本质都能够归为浏览器出于安全考虑下的同源 ...

  5. vue3.0和2.0的区别,Vue-cli3.0于 8月11日正式发布,更快、更小、更易维护、更易于原生、让开发者更轻松

    vue3.0和2.0的区别Vue-cli3.0于 8月11日正式发布,看了下评论,兼容性不是很好,命令有不少变化,不是特别的乐观vue3.0 的发布与 vue2.0 相比,优势主要体现在:更快.更小. ...

  6. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  7. JavaScript var关键字、变量的状态、异常处理、命名规范等介绍

    本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...

  8. JavaScript学习笔记(一)——延迟对象、跨域、模板引擎、弹出层、AJAX示例

    一.AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网页应用的开发技术.改善用户体验,实现无刷新效 ...

  9. atitit.管理学三大定律:彼得原理、墨菲定律、帕金森定律

    atitit.管理学三大定律:彼得原理.墨菲定律.帕金森定律 彼得原理(The Peter Principle) 1 彼得原理解决方案1 帕金森定律 2 如何理解墨菲定律2 彼得原理(The Pete ...

随机推荐

  1. Eclipse的一下设置

    一.设置自动补全 1.打开 Eclipse -> Window(窗口) -> Perferences(首选项) 2.点开java->Editor(编辑器)->Content A ...

  2. 【Linux】DNS服务-BIND基础配置

    1.BIND简介 现在使用最为广泛的DNS服务器软件是BIND(Berkeley Internet Name Domain),最早有伯克利大学的一名学生编写,现在最新的版本是9,有ISC(Intern ...

  3. mysql的时区错误问题,The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one

    在使用springboot整合ssm和druid的时候出现数据库一个问题 org.springframework.web.util.NestedServletException: Request pr ...

  4. AngularJs解决表达式闪烁的问题(ng-cloak)

    举例: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

  5. linux 配置环境变量

    配置全局 环境变量 查看环境变量 #这个变量赋值操作,只是临时生效,需要写入到文件,永久生效 echo $PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/u ...

  6. [转] node.js如何获取时间戳与时间差

    [From] http://www.jb51.net/article/89767.htm Nodejs中获取时间戳的方法有很多种,例如: 1.new Date().getTime()  2.Date. ...

  7. m3m4加载器的优化版m3m4-v1.1

    m3m4加载器的优化版m3m4-v1.1 /* //1.以$开头的模块名,表示服务,服务只会执行一次,它可以有自己的方法.比如cookie就是一个服务 //例如:console.log("r ...

  8. 合唱团---DP

    https://www.nowcoder.com/practice/661c49118ca241909add3a11c96408c8?tpId=85&tqId=29830&tPage= ...

  9. HDU 2879 数论

    HeHe Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submis ...

  10. Linux总线设备驱动模型

    1. Linux2.6内核引入总线.设备.驱动模型来描述各种总线(PCI.USB.I2C.SPI)与外围设备及其驱动之间的关系. 2. 在Linux内核中,总线用bus_type结构来描述,定义于文件 ...