放肆青春的博客
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)

放肆青春

一个前端菜鸟的技术成长之路
首页
前端
算法
网络
面试
技术
后端
运维
杂项
数据库
工具
网址
电脑
个人
文章
  • 分类
  • 标签
  • 归档
github (opens new window)
gitee (opens new window)
  • 前端

    • 前端 概览
    • 前端汇总

    • front 博文

    • front 项目总结

    • front 高级

    • front tools

  • vue

    • vue 概览
    • vue 汇总

    • vue 博文

    • vue 项目总结

    • vue 高级

  • html

    • html 概览
    • html 汇总

    • html 博文

  • css

    • css 概览
    • css 汇总

    • css 博文

    • sass

    • less

  • js

    • javascript 概览
    • JS 汇总

    • ES6

    • JS 博文

      • js 基础语法
      • js 数据类型
      • js 字符串
      • js 数组
      • js 对象
      • js 变量
      • js 函数
      • js 事件
      • js 循环
        • js 数组循环
          • 1. for
          • 2. for of
          • 3. map
          • 4. forEach
          • for-in 和 for-of 区别
          • map 和 forEach 区别
        • js 对象循环
          • 1. for in
          • 2. Object.keys()
          • 3. Object.getOwnPropertyNames
          • 4. Reflect.ownKeys
          • Object.keys 和 for in 区别
        • js Symbol 循环
          • 1. Object.getOwnPropertySymbols()
          • 2. Reflect.ownKeys
      • js 浅拷贝和深拷贝
      • js 动画
      • js DOM
      • js 防抖节流
      • js 原型及原型链
      • js this
      • js 作用域
      • js 继承
      • js 闭包
      • js 内存
      • js垃圾回收
    • JS 工具

  • node

    • node 概览
    • node 汇总

    • node 框架

    • node 博文

  • react

    • react 概览
    • react 汇总

    • react 博文

    • react 高级

  • 微信小程序

    • 微信小程序 概览
    • 微信小程序总结
    • 微信小程序文章
    • 微信小程序 博文

    • 微信小程序 高级

  • 微信公众号

    • 微信公众号 概览
    • 微信公众号总结
    • 微信公众号文章
  • 多端开发

    • 多端开发
    • dsbridge 概览
    • jsbridge 概览
    • webview
    • uniapp

      • uniapp 概览
    • taro

      • taro 概览
    • flutter

      • flutter 概览
      • flutter 环境搭建
    • electron

      • electron 概览
  • front
放肆青春
2020-07-09

js 循环

# js 数组循环

# 1. for

适用范围:数组

简介:

  • 1、for 有三个表达式:① 声明循环变量;② 判断循环条件;③ 更新循环变量;三个表达式之间,用;分割,for 循环三个表达式都可以省略,但是两个“;”缺一不可。

  • 2、for 循环的执行特点:先判断再执行,与 while 相同

  • 3、for 循环三个表达式都可以有多部分组成,第二部分多个判断条件用&& ||连接,第一三部分用逗号分割;

# 2. for of

适用范围:Array、Map、Set、String、TypedArray、函数的 arguments 对象、NodeList 对象等拥有迭代器对象(iterator)的集合

ES6 借鉴 C++、Java、C# 和 Python 语言,引入了 for...of 循环,作为遍历所有数据结构的统一的方法。

一个数据结构只要部署了 Symbol.iterator 属性,就被视为具有 iterator 接口,就可以用 for...of 循环遍历它的成员。 也就是说,for...of 循环内部调用的是数据结构的 Symbol.iterator 方法。 for...of 循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象(比如 arguments 对象、DOM NodeList 对象)、后文的 Generator 对象,以及字符串。

for of 怎么遍历对象?

  1. 使用 Object.keys
const obj = {
  a: 1,
  b: 2,
  c: 3,
};

for (let i of Object.keys(obj)) {
  console.log(i);
  // 1
  // 2
  // 3
}
1
2
3
4
5
6
7
8
9
10
11
12
  1. 实现 iterator 接口
const obj = {
  e: 5,
  f: 6,
};

newObj[Symbol.iterator] = function*() {
  let keys = Object.keys(this);
  for (let i = 0, l = keys.length; i < l; i++) {
    yield {
      key: keys[i],
      value: this[keys[i]],
    };
  }
};

for (let { key, value } of newObj) {
  console.log(key, value);
}
// 输出结果
// e 5
// f 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 3. map

适用范围:数组

以一个数组的每一项为基础,构造出一个新数组。

  • 语法: arr.map(function(self,index,arr){},this); 和 forEach 一致

self:数组当前遍历的元素,默认从左往右依次获取数组元素。

index:数组当前元素的索引,第一个元素索引为 0,依次类推。

arr:当前遍历的数组。

this:回调函数中 this 指向。

# 4. forEach

适用范围:数组

forEach 对数组的每一项执行同样的操作

  • 语法: arr.forEach(function(self,index,arr){},this);

self:数组当前遍历的元素,默认从左往右依次获取数组元素。

index:数组当前元素的索引,第一个元素索引为 0,依次类推。

arr:当前遍历的数组。

this:回调函数中 this 指向。

  • 注意点

    1. forEach 不支持 break
    2. forEach 中使用 return 无效
    3. forEach 删除自身元素 index 不会被重置

可改变原数组情况:

var a = [1, "1", { num: 1 }, true];
a.forEach((item, index, arr) => {
  item.num = 2;
  item = 2;
});
console.log(a);
// [1,'1',{num:2},true]
// 改变原因:由于对象是引用类型,新对象和旧对象指向的都是同一个地址,所以新对象把num变成了2,原数组中的对象也改变了

var a = [1, 2, 3, 4, 5];
a.forEach((item, index, arr) => {
  arr[index] = item * 2;
});
console.log(a);
// [2,4,6,8,10]
// 改变原因:同上,参数中的arr也只是原数组的一个拷贝,如果修改数组中的某一项则原数组也改变因为指向同一引用地址
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

不可改变原数组情况:

var a = [1, 2, 3, 4, 5];
a.forEach((item) => {
  item = item * 2;
});
console.log(a);
// [1,2,3,4,5]
// 不改变原因:因为item的值并不是相应的原数组中的值,而是重新建立的一个新变量,值和原数组相同。

var a = [1, "1", { num: 1 }, true];
a.forEach((item, index, arr) => {
  item = 2;
});
console.log(a);
// [1,'1',{num:1},true]
// 不改变原因:数组中的对象的值也没有改变,是因为新创建的变量和原数组中的对象虽然指向同一个地址,但改变的是新变量的值,即新对象的值为2,原数组中的对象还是{num:1}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

上面改变不改变的原因:

核心原理:栈(stack)内存和堆(heap)内存

JS 中的基本数据类型是存在于栈内存中,在栈内存中储存变量名及相应的值。而 Object,Array,Function 存在于堆内存中,栈中储存对象的地址指针,堆内存储存变量名及相应的值

详解: https://www.cnblogs.com/echolun/p/11544045.html (opens new window)

# for-in 和 for-of 区别

  1. for of 循环用来获取一对键值对中的值,而 for in 获取的是 键名

  2. 适用场景不同

for of 适用遍历数/数组对象/字符串/map/set 等拥有迭代器对象(iterator)的集合,但是不能遍历对象

for in 更适合遍历对象,当然也可以遍历数组,但是会存在一些问题,

(1)for...in 循环数组是以字符串作为键名“0”、“1”、“2”

(2)特别情况下, for ... in 循环会以看起来任意的顺序遍历键名

  • 详解: https://www.cnblogs.com/baiyunke/p/7821299.html (opens new window)

# map 和 forEach 区别

  1. 返回值:

forEach()方法不会返回执行结果,而是 undefined,不可以链式调用。

map()方法会得到一个新的数组并返回,可以与其他方法(如 reduce()、sort()、filter())链接在一起

相同点:

  1. 对空数组不会调用回调函数

  2. 两种方法都不能用 break 中断,否则会引发异常(不能使用 break 跳出整个循环,不能使用 continue 跳出本次循环)

  3. map 和 forEach 都没有 for 循环快

# js 对象循环

# 1. for in

适用范围:对象

for in 概念:以任意顺序遍历一个对象的除 Symbol 以外的可枚举属性,包括继承的可枚举属性。

for-in 语法:for(keys in zhangsan){}

keys 表示 obj 对象的每一个键值对的键!!所有循环中,需要使用 obj[keys]来取到每一个值!!!

for-in 循环,遍历时不仅能读取对象自身上面的成员属性,也能延续原型链遍历出对象的原型属性

所以,可以使用 hasOwnProperty 判断一个属性是不是对象自身上的属性。

obj.hasOwnProperty(keys)==true 表示这个属性是对象的成员属性,而不是原先属性

使用 for in 也可以遍历数组,但是会存在以下问题:

  1. for in 遍历的是数组的索引(即键名),而 for of 遍历的是数组元素值。

  2. 特别情况下, for ... in 循环会以看起来任意的顺序遍历键名

  3. 使用 for in 会遍历数组所有的可枚举属性,包括原型属性

  4. index 索引为字符串型数字,不能直接进行几何运算

  5. for in 会遍历手动添加的其他键

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

for (var i in obj) {
  console.log(i, ":", obj[i]);
}
1
2
3
4
5

# 2. Object.keys()

返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性).

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

Object.keys(obj).forEach(function(key) {
  console.log(key, obj[key]);
});
1
2
3
4
5

# 3. Object.getOwnPropertyNames

返回一个数组,包含对象自身的(不含继承的)所有属性(不含 Symbol 属性,但是包括不可枚举属性)

var obj = { "0": "a", "1": "b", "2": "c" };
Object.getOwnPropertyNames(obj).forEach(function(key) {
  console.log(key, obj[key]);
});
1
2
3
4

# 4. Reflect.ownKeys

返回一个数组,包含对象自身的所有属性,不管属性名是 Symbol 或字符串,也不管是否可枚举.但不包括继承自原型的属性

var obj = { "0": "a", "1": "b", "2": "c" };
Reflect.ownKeys(obj).forEach(function(key) {
  console.log(key, obj[key]);
});
1
2
3
4

# Object.keys 和 for in 区别

  1. Object.keys()不会走原型链,而 for in 会走原型链;

  2. Object.keys()会返回一个数组,而 for in 无返回值;

# js Symbol 循环

# 1. Object.getOwnPropertySymbols()

const obj = {};
const foo = Symbol("foo");

obj[foo] = "bar";

for (let i in obj) {
  console.log(i); // 无输出
}

Object.getOwnPropertyNames(obj); // []
Object.getOwnPropertySymbols(obj); // [Symbol(foo)]
1
2
3
4
5
6
7
8
9
10
11

# 2. Reflect.ownKeys

Reflect.ownKeys()方法可以返回所有类型的键名,包括常规键名和 Symbol 键名。

返回一个数组,

let obj = {
  [Symbol("my_key")]: 1,
  enum: 2,
  nonEnum: 3,
};

Reflect.ownKeys(obj);
//  ["enum", "nonEnum", Symbol(my_key)]
1
2
3
4
5
6
7
8
更新时间: 2/10/2022, 7:21:32 PM
js 事件
js 浅拷贝和深拷贝

← js 事件 js 浅拷贝和深拷贝→

最近更新
01
前端权限管理
02-24
02
vue2指令
02-24
03
vue2 hook
02-24
更多文章>
Theme by Vdoing | Copyright © 2019-2022 放肆青春
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式