js 之 for循环
js之 for循环
普通for 循环
语法
for ([initialization]; [condition]; [final-expression])
statement
initialization
- 一个表达式 (包含赋值语句) 或者变量声明。典型地被用于初始化一个计数器。该表达式可以使用
var
关键字声明新的变量。初始化中的变量不是该循环的局部变量,而是与for
循环处在同样的作用域中。该表达式的结果无意义。 condition
- 一个条件表达式被用于确定每一次循环是否能被执行。如果该表达式的结果为true,
statement
将被执行。 这个表达式是可选的。如果被忽略,那么就被认为永远为真。如果计算结果为假,那么执行流程将被跳到for
语句结构后面的第一条语句。 final-expression
- 每次循环的最后都要执行的表达式。执行时机是在下一次
condition
的计算之前。通常被用于更新或者递增计数器变量。 statement
- 只要
condition
的结果为true就会被执行的语句。 要在循环体内执行多条语句,使用一个块语句({ ... }
)来包含要执行的语句。没有任何语句要执行,使用一个空语句(;
)。
事例
for (var i = 0; i < 9; i++) {
console.log(i);
// more statements
}
for await...of
语法
for await (variable of iterable) {
statement
}variable
在每次迭代时,将不同属性的值分配给变量。iterable
迭代其可迭代属性的对象。 事例:
async function* asyncGenerator() {
var i = 0;
while (i < 3) {
yield i++;
}
} (async function() {
for await (num of asyncGenerator()) {
console.log(num);
}
})();
//
//
//
for each...in
语法
for each (variable in object) {
statement
}
variable
- 用来遍历属性值的变量,前面的
var
关键字是可选的.该变量是函数的局部变量而不是语句块的局部变量.
object
- 该对象的属性值会被遍历.
statement
- 遍历属性值时执行的语句. 如果想要执行多条语句, 请用(
{ ... }
) 将多条语句括住.
事例:
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的值
警告:永远不要使用for each...in语句遍历数组,仅用来遍历常规对象
for...in
语法
for (variable in object) {...}
variable
- 在每次迭代时,将不同的属性名分配给变量。
object
- 被迭代枚举其属性的对象
-
描述
for...in
循环只遍历可枚举属性。像Array
和Object
使用内置构造函数所创建的对象都会继承自Object.prototype
和String.prototype
的不可枚举属性,例如String
的indexOf()
方法或Object
的toString()
方法。循环将遍历对象本身的所有可枚举属性,以及对象从其构造函数原型中继承的属性(更接近原型链中对象的属性覆盖原型属性)。删除,添加或者修改属性
for...in
循环以任意序迭代一个对象的属性(请参阅delete
运算符,了解为什么不能依赖于迭代的表面有序性,至少在跨浏览器设置中)。如果一个属性在一次迭代中被修改,在稍后被访问,其在循环中的值是其在稍后时间的值。一个在被访问之前已经被删除的属性将不会在之后被访问。在迭代进行时被添加到对象的属性,可能在之后的迭代被访问,也可能被忽略。通常,在迭代过程中最好不要在对象上进行添加、修改或者删除属性的操作,除非是对当前正在被访问的属性。这里并不保证是否一个被添加的属性在迭代过程中会被访问到,不保证一个修改后的属性(除非是正在被访问的)会在修改前或者修改后被访问,不保证一个被删除的属性将会在它被删除之前被访问。数组迭代和
for...in
提示:
for...in
不应该用于迭代一个Array
,其中索引顺序很重要。数组索引只是具有整数名称的枚举属性,并且与通用对象属性相同。不能保证
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"var triangle = {a: 1, b: 2, c: 3}; function ColoredTriangle() {
this.color = 'red';
} ColoredTriangle.prototype = triangle; var obj = new ColoredTriangle(); for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
console.log(`obj.${prop} = ${obj[prop]}`);
}
} // Output:
// "obj.color = red"
for...of
语法
for (variable of iterable) {
//statements
}variable
在每次迭代中,将不同属性的值分配给变量。iterable
被迭代枚举其属性的对象。
示例
迭代Array
let iterable = [10, 20, 30]; for (let value of iterable) {
value += 1;
console.log(value);
}
//
//
//
如果你不想修改语句块中的变量 , 也可以使用const
代替let
。
let iterable = [10, 20, 30]; for (const value of iterable) {
console.log(value);
}
//
//
//
迭代String
let iterable = "boo"; for (let value of iterable) {
console.log(value);
}
// "b"
// "o"
// "o"
迭代 TypedArray
节
let iterable = new Uint8Array([0x00, 0xff]); for (let value of iterable) {
console.log(value);
}
//
//
迭代Map
let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]); for (let entry of iterable) {
console.log(entry);
}
// ["a", 1]
// ["b", 2]
// ["c", 3] for (let [key, value] of iterable) {
console.log(value);
}
//
//
//
迭代 Set
let iterable = new Set([1, 1, 2, 2, 3, 3]); for (let value of iterable) {
console.log(value);
}
//
//
//
迭代 arguments
对象
(function() {
for (let argument of arguments) {
console.log(argument);
}
})(1, 2, 3); //
//
//
迭代 DOM 集合
迭代 DOM 元素集合,比如一个NodeList
对象:下面的例子演示给每一个 article 标签内的 p 标签添加一个 "read
" 类。
//注意:这只能在实现了NodeList.prototype[Symbol.iterator]的平台上运行
let articleParagraphs = document.querySelectorAll("article > p"); for (let paragraph of articleParagraphs) {
paragraph.classList.add("read");
}
关闭迭代器
对于for...of
的循环,可以由break
, throw
或return
终止。在这些情况下,迭代器关闭。
function* foo(){
yield 1;
yield 2;
yield 3;
}; for (let o of foo()) {
console.log(o);
break; // closes iterator, triggers return
}
迭代生成器
你还可以迭代一个生成器:
function* fibonacci() { // 一个生成器函数
let [prev, curr] = [0, 1];
for (;;) { // while (true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
} for (let n of fibonacci()) {
console.log(n);
// 当n大于1000时跳出循环
if (n >= 1000)
break;
}
不要重用生成器
生成器不应该重用,即使for...of
循环的提前终止,例如通过break
关键字。在退出循环后,生成器关闭,并尝试再次迭代,不会产生任何进一步的结果。
var gen = (function *(){
yield 1;
yield 2;
yield 3;
})();
for (let o of gen) {
console.log(o);
break;//关闭生成器
} //生成器不应该重用,以下没有意义!
for (let o of gen) {
console.log(o);
}
迭代其他可迭代对象
你还可以迭代显式实现可迭代协议的对象:
var iterable = {
[Symbol.iterator]() {
return {
i: 0,
next() {
if (this.i < 3) {
return { value: this.i++, done: false };
}
return { value: undefined, done: true };
}
};
}
}; for (var value of iterable) {
console.log(value);
}
//
//
//
for...of
与for...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.prototype
和Array.prototype
。由于继承和原型链,对象iterable
继承属性objCustom
和arrCustom
。
for (let i in iterable) {
console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom"
}
此循环仅以原始插入顺序记录iterable
对象的可枚举属性。它不记录数组元素3
, 5
, 7
或hello
,因为这些不是枚举属性。但是它记录了数组索引以及arrCustom
和objCustom
。如果你不知道为什么这些属性被迭代,array iteration and for...in
中有更多解释。
for (let i in iterable) {
if (iterable.hasOwnProperty(i)) {
console.log(i); // logs 0, 1, 2, "foo"
}
}
这个循环类似于第一个,但是它使用hasOwnProperty()
来检查,如果找到的枚举属性是对象自己的(不是继承的)。如果是,该属性被记录。记录的属性是0
, 1
, 2
和foo
,因为它们是自身的属性(不是继承的)。属性arrCustom
和objCustom
不会被记录,因为它们是继承的。
for (let i of iterable) {
console.log(i); // logs 3, 5, 7
}
该循环迭代并记录iterable
作为可迭代对象定义的迭代值,这些是数组元素 3
, 5
, 7
,而不是任何对象的属性。
摘取自MDN
js 之 for循环的更多相关文章
- js 控制Div循环显示 非插件版
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- js种的循环语句
//js种的循环语句 //while与do while的区别是while是满足条件后才执行 //do while是不管满不满足条件都会执行一次 //for 循环与while,do while相比循环结 ...
- js中的循环语句
js中的循环语句可分为三种:1.while:2.do……while:3.for. while的语法为 while (exp) { //statements;} var a=1,b=0; whil ...
- js的事件循环绑定和jQuery的隐式迭代
js的事件循环绑定和jQuery的隐式迭代 js事件循环绑定 jQuery隐式迭代 先举一个例子:给定一个ul,点击列表内的每一个li元素,使它的背景色变红,下边分别用js代码和jQuery实现. & ...
- 原生JS—实现图片循环切换的两种方法
今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法.多余的话我们就不多说了,我们一个一个开始讲吧. 1 原生JS实现图片循环切换 -- 方法一 在上栗子之前我们先简单介绍一下所用的一些知识点. ...
- 原生JS—实现图片循环切换及监测鼠标滚动切换图片
今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法以及如何检测鼠标滚动循环切换图片.多余的话我们就不多说了,我们一个一个开始讲吧. 1 原生JS实现图片循环切换 -- 方法一 在上栗子之前我们 ...
- js中的循环
js中的循环是我们经常要用到的,现在进行一些归纳. 一.javascript种的循环. 1.循环对象 var o = { name: 'Jack', age: 20, city: 'Beijing' ...
- JS JavaScript事件循环机制
区分进程和线程 进程是cpu资源分配的最小单位(系统会给它分配内存) 不同的进程之间是可以同学的,如管道.FIFO(命名管道).消息队列 一个进程里有单个或多个线程 浏览器是多进程的,因为系统给它的进 ...
- js:for循环ul/li,获取当前被点击元素的id,以及给其他li设置属性
js:for循环ul/li,获取当前被点击元素的id,以及给其他li设置属性 <!doctype html> <html> <head> <meta char ...
- Node.js:事件循环
ylbtech-Node.js:事件循环 1.返回顶部 1. Node.js 事件循环 Node.js 是单进程单线程应用程序,但是通过事件和回调支持并发,所以性能非常高. Node.js 的每一个 ...
随机推荐
- JavaScript-原始值和引用值
一.原始值和引用值的概念 在 ECMAScript 中,变量可以存在两种类型的值,即原始值和引用值. 1.1 原始值 (1)原始值指的是 原始类型 的值,也叫 基本类型,例如 Number.Stirn ...
- 1005 Spell It Right (20 分)
Given a non-negative integer N, your task is to compute the sum of all the digits of N, and output e ...
- 【电商】性能测试网站搭建:XAMPP1.8+DBShop1.3
1.安装准备 1.1软件版本 XAMPP的版本:XAMPP 1.8.2 DBShop的版本:DBShop 1.3 1.2.安装环境 我的环境:win10 win7,win10都可以运行的,安装步骤 ...
- 关于json语句的相关用法
json语句: JSON 值可以是: 数字(整数或浮点数)字符串(在双引号中)逻辑值(true 或 false)数组(在中括号中)对象(在大括号中)null 对于json的的对象数组:var site ...
- How to setup a Alpine Linux mirror
How to setup a Alpine Linux mirror Contents 1 Introduction 2 Setting up the cron job 3 Setting up ...
- 「一闻秒懂」你了解goroutine和channel吗?
开源库「go home」聚焦Go语言技术栈与面试题,以协助Gopher登上更大的舞台,欢迎go home~ 背景介绍 大家都知道进程是操作系统资源分配的基本单位,有独立的内存空间,线程可以共享同一个进 ...
- PyJWT 详解
1.首先,我们需要先了解 JWT 的概念,所以我们先看pyjwt的官网 https://jwt.io/ 2.对于官方 JWT 有两篇博文写的不错分别如下: https://blog.csdn.net/ ...
- "一号标题"组件:<h1> —— 快应用组件库H-UI
 <import name="h1" src="../Common/ui/h-ui/text/c_h1"></import> < ...
- hadoop(五)scp命令copy文件和配置(完全分布式准备二)|7
机器的克隆参考centos7克隆ip|机器名|映射关系|别名配置(hadoop完全分布式准备一) 那么问题来了,如果我们有30台机器,之间可以互相访问,那我们如何快速安装配置环境如jdk hadoop ...
- docker安装GD扩展
apt update #更新软件源 apt install -y libwebp-dev libjpeg-dev libpng-dev libfreetype6-dev #安装各种库 docker-p ...