IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> ES6新特性:解构、对象扩展、函数扩展、数组扩展 -> 正文阅读

[JavaScript知识库]ES6新特性:解构、对象扩展、函数扩展、数组扩展

解构

1、什么是解构

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring),解构的本质属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。如果解构不成功,变量的值就等于undefined

2、数组解构

  • 拓展运算符
    拓展运算符使用三个点(…)表示。好比将一个数组转为用逗号分隔的参数序列。
    例如:
let arr1 = [1,2,3];
let arr2 = [4,5,6];

// 数组合并
let arr = [...arr1,...arr2];
console.log(arr);
// 打印出:[1,2,3,4,5,6]

// 字符串转换为数组
let temp = [..."hello"];   
console.log(temp);
// 打印出:['h','e','l','l','o']
  • 数组解构
    以前为变量赋值时只能直接指定值,如下
let a = 1;
let b = 2;
let c = 3;

ES6 允许写成下面这样。等号左边的变量放到中括号内部,匹配右侧数组中的元素。

let [a, b, c] = [1, 2, 3]; 

上面代码表示,可以从数组中提取值,按照对应位置,对变量赋值。
本质上,这种写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
看如下例子:

//注意变量与值会按照索引一一对应
let [foo, [[bar], baz]] = [1, [[2], 3]];
//结果如下:
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3

//当未指定变量名时
let [ , , third] = ["foo", "bar", "baz"];
//结果如下:
console.log(third); // "baz"

//与索引一一对应
let [x, , y] = [1, 2, 3];
x // 1
y // 3

//...变量名 表示匹配前面变量未匹配到的值,存在数组中
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]


let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

//如果解构不成功,变量的值就等于undefined
let [bar, foo] = []; 
let [bar, foo] = [1];
//以上两种情况都属于解构不成功,`foo`的值都会等于`undefined`

不完全解构

不完全解构,即等号左边的模式,只匹配一部分的等号右边的数组。这种情况下,解构依然可以成功。

let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2    //以内[b]和[2,3]的模式相同,所以只会匹配到2
d // 4

如果等号的右边不是数组(或者严格地说,不是可遍历的结构)那么将会报错.

// 报错
let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {};

// 可以正常解构
let [a] = 'hello';
a // 'h'

上面的六个表达式都会报错,因为等号右边的值,要么转为对象以后不具备 Iterator 接口(前五个表达式),要么本身就不具备 Iterator 接口(最后一个表达式)。

事实上,只要某种数据结构具有 Iterator 接口,都可以采用数组形式的解构赋值。原生具备 Iterator 接口的数据结构:Array、Map、Set、String、TypedArray、arguments、NodeList 等。

集合结构
使用...扩展运算符接收剩余的数据

let old = [1, 2, 3, 4]
let [...arr] = old;
console.log(old); //[ 1, 2, 3, 4 ]
console.log(arr)  //[ 1, 2, 3, 4 ]
console.log(arr === old);//false

待补充解释。。。

默认值
解构赋值允许指定默认值。注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效。

let [x, y = 'b'] = ['a'];   
// x='a', y='b’

//默认值也可以为函数
function f() { console.log('aaa'); } 
let [x = f()] = [1]; 
// x = 1,该f函数不会执行,函数在x取到undefined的时候才会执行,并将返回值赋值给x,如下
let [y = f] = []; 
// y = f
let [z = f()] = [];
// z = undefined

3、对象解构

对象解构指的是将等号左边的变量放到大括号内部,匹配右侧数组中的元素。
对象的属性没有次序,变量必须与属性同名,才能取到正确的值。如下:

let { foo, bar } = { foo: "aaa", bar: "bbb" };	
// foo = "aaa"; bar = "bbb"

重命名结构
如果变量名与属性名不一致,必须写成下面这样进行重命名。

let { foo: baz } = { foo: 'aaa', bar: 'bbb' };  
// baz = "aaa"

这实际上说明,对象的解构赋值是下面形式的简写。

let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" };

嵌套解构

let obj = { p: [ "Hello", { y: "World" } ] };   
let { p: [x, { y }] } = obj;  
// x = "Hello”; y = "World"

默认值

默认值生效的条件是,对象的属性值严格等于undefined

let {x: y = 3} = { x: 1 }; 
// y = 1
let {x: y = 3} = {}; 
// y = 3

运算符…
**…用到左侧是聚合,…**用到右侧就是展开

let obj = { name: 'zhangsan', age: 12 }
//==========================================
let { ...person } = obj
person.gender = "1"; //给对象中添加属性和属性值
console.log(person)//{ name: 'zhangsan', age: 12, gender: '1' }
console.log(person === obj)//false
//person是重新创建的一个对象,所以并不等于obj

//==========================================
let stu = {
  ...obj,
  gender: '1'
}
console.log(stu) //{ name: 'zhangsan', age: 12, gender: '1' }

let {gender="2",...zs} = stu;
console.log(gender,zs)//1 { name: 'zhangsan', age: 12 }

4、字符串解构

等号左边的变量如果放在中括号内进行的类似于数组解构,从字符串中获取指定字符;如果放在大括号内进行的类似于对象解构,从实例属性获方法中解构。

const [a, b, c, d, e] = 'hello';   
// a = h;b = e;c = l;d = l;e = o

let {length : len, toString } = 'hello';   
// len = 5

//将string字符串转成数组
let [...arr] = 'hello';
console.log(arr); //[ 'h', 'e', 'l', 'l', 'o' ]

5、其他不咋用解构

数值解构

等号左边的变量放在大括号中进行解构,可以获取到数值包装器构造函数原型中指定的方法。

let { valueOf } = 12;   
// valueOf = Number.prototype.valueOf

布尔类型解构

等号左边的变量放在大括号中进行解构,可以获取到布尔包装器构造函数原型中指定的方法。

let { valueOf } = true;   
// valueOf = Boolean.prototype.valueOf

常用扩展

1、对象扩展

ES6中对于Object的拓展主要是静态方法的拓展。

  1. Object.is()
    该方法用来判断两个值是否“相等”,或者说是否为同一个值。
    格式:Object.is(value1,value2);
    结果:返回一个Bolean类型表示两个参数是否为同一个值。为true则相同,为false表示不同

该方法和"=="有区别:
"==“在判断相等前对两边的变量(如果不是同一类型)进行强制转换,而Object.is()方法不会这么做
该方法和”==="也有区别:
“===“先比较类型,类型不相同则结果一定不等,如果类型相同,则继续比较值,值相等,则结果相等。并且”===” 将数字 -0 和 +0 视为相等,而将Number.NaN 与NaN视为不相等,而Object.is()方法将这两个均视为不等。

Object.is('foo', 'foo');  // true
Object.is(window, window);  // true
Object.is('foo', 'bar');   // false,这是两个对象,存放的地址位置不同
Object.is([], []);  // false,这是两个对象,存放的地址位置不同

let foo = { a: 1 };
let bar = { a: 1 };
Object.is(foo, foo); // true
Object.is(foo, bar); // false,这是两个对象,存放的地址位置不同

Object.is(null, null); // true
console.log(1 === 1);//true
console.log(Object.is(1, 1));//true
console.log(Object.is(1, 2)); //false

console.log(+0 === -0);  //true
console.log(Object.is(+0, -0));  //false

console.log(0 === -0);  //true
console.log(Object.is(0, -0));  //false

console.log(NaN === NaN); //false
console.log(Object.is(NaN, NaN));  //true

console.log(isNaN(NaN)); //true

console.log(NaN === 0/0); //false

console.log(Object.is(NaN, 0/0));  //true

简单理解就是Object.is()方法比较值其实就是看两个值的存储位置是不是一样,一样则相等。

  1. Object.assign()
    该方法用于将所有可枚举类型的值从一个或多个源对象分配到目标对象。返回目标对象
    语法:object.assign(target,...sources);target是目标对象,sources源对象,而可以为一个或多个。

如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性,此外需要注意Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。看如下例子

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// Object { a: 1, b: 4, c: 5 }

补充:该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。
如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()和Object.defineProperty()。
Object.assign()拷贝的是(可枚举)属性值。假如源值是一个对象的引用,它仅仅会复制其引用值。

  1. Object.getPrototypeOf()
    该方法返回指定对象的原型。
    语法:Object.getPrototypeOf(object);object是要返回其原型的对象
    返回的是给定对象的原型,如果没有继承属性则返回null
let obj = {};
// 获取obj的原型对象
console.log(Object.getPrototypeOf(obj));
// 打印出:obj的原型对象
console.log(Object.getPrototypeOf(obj)===Object.prototype);
//打印出:true
console.log(Object.getPrototypeOf(obj)===obj.__proto__);
//打印出:true
  1. Object.setPrototypeOf()
    该方法方法设置一个指定的对象的原型到另一个对象或 null。
    语法:Object.setPrototypeOf(obj,prototype);obj是要设置其原型的对象,protoType是该对象obj的新原型
let dict = Object.setPrototypeOf({}, null);

由于现代 JavaScript 引擎优化属性访问所带来的特性的关系,更改对象的 [[Prototype]]在各个浏览器和 JavaScript 引擎上都是一个很慢的操作。其在更改继承的性能上的影响是微妙而又广泛的,这不仅仅限于 obj.proto = … 语句上的时间花费,而且可能会延伸到任何代码,那些可以访问任何[[Prototype]]已被更改的对象的代码。如果关心性能,应该避免设置一个对象的 [[Prototype]]。相反,应该使用 Object.create()来创建带有想要的[[Prototype]]的新对象。

  1. Object.keys()
    该方法用于获取所有可枚举属性名,并且返回一个有一个给定对象自身可枚举属性组成的数组,数组中属性名的排序和正常循环遍历该对象时返回的顺序一致。
    语法:object.keys(obj); obj是要返回其枚举自身属性的对象。
//例如一个简单的数组
let arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); 
// 打印出: ['0', '1', '2']

// 例如一个对象数组
let obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.keys(obj)); // ['0', '1', '2']
//遍历
Object.keys(obj).forEach((item) => {
  console.log(item, obj[item]);
})

//一个带有随机排序key的对象数组。
let anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.keys(anObj));  // ['2', '7', '100']

// getFoo is a property which isn't enumerable
let myObj = Object.create({}, {
	getFoo: {
		value: function () { return this.foo; }
	}
});
myObj.foo = 1;
console.log(Object.keys(myObj)); 
// 打印出: ['foo']

当然,如果想获取一个对象的所有属性,甚至包括不可枚举的,请使用Object.getOwnPropertyNames()方法。

  1. Object.value()
    该方法可以获取所有可枚举属性的属性值,并返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for…in循环的顺序相同(区别在于for-in循环枚举原型链中的属性)。
    语法:Object.values(obj); obj表示可以枚举属性值的对象。
let obj = { foo: 'bar', baz: 42 };
console.log(Object.values(obj)); // ['bar', 42]

let obj = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.values(obj));  // ['a', 'b', 'c']

// array like object with random key ordering
// when we use numeric keys, the value returned in a numerical order according to the keys
let an_obj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.values(an_obj));  // ['b', 'c', 'a']

// getFoo is property which isn't enumerable
let my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
my_obj.foo = 'bar';
console.log(Object.values(my_obj)); 
// 打印出: ['bar']

// non-object argument will be coerced to an object
console.log(Object.values('foo')); 
// 打印出: ['f', 'o', 'o']
  1. Object.entries
    该方法获取所有的可枚举属性名和属性值键值对返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for…in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
    语法:Object.entries(obj);obj 可以返回其可枚举属性的键值对的对象。
const obj = { foo: 'bar', baz: 42 };
console.log(Object.entries(obj)); // [ ['foo', 'bar'], ['baz', 42] ]

// array like object
const obj2 = { 0: 'a', 1: 'b', 2: 'c' };
console.log(Object.entries(obj)); 
// 打印出: [ ['0', 'a'], ['1', 'b'], ['2', 'c'] ]

// array like object with random key ordering
const anObj = { 100: 'a', 2: 'b', 7: 'c' };
console.log(Object.entries(anObj)); 
// 打印出: [ ['2', 'b'], ['7', 'c'], ['100', 'a'] ]

// getFoo is property which isn't enumerable
const myObj = Object.create({}, { getFoo: { value() { return this.foo; } } });
myObj.foo = 'bar';
console.log(Object.entries(myObj)); 
// 打印出: [ ['foo', 'bar'] ]

// non-object argument will be coerced to an object
console.log(Object.entries('foo')); 
// 打印出: [ ['0', 'f'], ['1', 'o'], ['2', 'o'] ]

// iterate through key-value gracefully
const obj3 = { a: 5, b: 7, c: 9 };
for (const [key, value] of Object.entries(obj)) {
	console.log(`${key} ${value}`); 
	// 打印出: "a 5", "b 7", "c 9"
}

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key} ${value}`); 
// 打印出: "a 5", "b 7", "c 9"
});

2、函数扩展

  • 函数参数
    ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。通常情况下,定义了默认值的参数,应该是函数的尾参数,并且注意:函数的length属性,将返回没有指定默认值的参数个数

  • 设置默认值

function log(x, y = 'World') { 
	console.log(x, y);
	// 打印出:1,'World'
}
log(1);
  • 参数结构
    参数默认值可以与解构赋值的默认值,结合起来使用。
function foo({x, y = 5}) { 
	console.log(x, y); 
	// 打印出:1,5
}
foo({x:1});

此外,函数参数对象解构、数据结构等。

function test({ name, age = 1, ...obj }) {
  console.log(name, age, obj);
}
test({ name: 'zhangsan', age: 12, gender: 1,weight:40 });
//zhangsan 12 { gender: 1, weight: 40 }
  • rest参数
    ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数得到一个数组,这样就不需要使用arguments对象了。
function add(...values) {
	console.log(values);
	// 打印出:[2,5,3]
}
add(2, 5, 3)

箭头函数

JavaScript中,经常使用回调函数,箭头函数的出现大大简化了回调函数的写法,当然,除了作为函数参数,箭头函数也可以出现在其他地方。
果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回
语法:(0个或1个或多个参数)=>{代码块部分}
箭头函数里面没有自己的this,而是引用外层作用域中的this,与传统的JavaScript函数有些不同,具体看下面几点:

  • 没有thissuperarguments
  • 不能通过new关键字调用
  • 没有原型prototype
  • 不可以改变this指向
  • 不支持重复的命名参数

使用如下:

let f = v => v;
// 等价于
let f = function(v) { 
	return v; 
};

let obj = {
  name:"terry",
  say1:function(){
    console.log(this.name)
  },
  say2() {
    console.log(this.name)
  },
  say3: () => {
    console.log(this)   //global
  },
  say4() {
    return () => {
      console.log(this);//obj
    }
  }
};

obj.say1();
obj.say2();
obj.say3();
obj.say4()();

重点:
如果将普通匿名函数和箭头函数分别定义在setTimeout(function(),时间)中。那么区别在哪里?如下:

var obj = {
	x:100,
	show(){
		//延迟500毫秒,输出x的值
		setTimeout(){
			()=>{console.log(this.x);),
			500
		);
	}
};

使用箭头函数简写时,this调用的对象时obj

var obj = {
	x:100,
	show(){
		//延迟500毫秒,输出x的值
		setTimeout(){
			function(){console.log(this.x);),
			500
		);
	}
};

使用匿名函数时,this调用的对象时全局对象,因为匿名函数是在延时器setTimeout()中,而延时器又不在主线程内,所以是全局对象在调用。

这其实也是作用域链的问题,只不过最顶部的作用域对象不同。

3、数组扩展

数组在静态方法与实例方法中都有所拓展。

  • Array.from()
    该方法将类似数组或可迭代对象转为数组,从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。
    语法:Array.from(arrayLike[, mapFn[, thisArg]])
    参数:
    • arrayLike 想要转换成数组的伪数组对象或可迭代对象。
    • mapFn 可选 如果指定了该参数,新数组中的每个元素会执行该回调函数。
    • thisArg 可选 执行回调函数 mapFn 时 this 对象。

Array.from() 可以通过以下方式来创建数组对象:
伪数组对象(拥有一个 length 属性和若干索引属性的任意对象)
可迭代对象(可以获取对象中的元素,如 Map和 Set 等)

Array.from('foo');
// [ "f", "o", "o" ]

function f() {
	return Array.from(arguments);
}
f(1, 2, 3);
// [ 1, 2, 3 ]
  • Array.of()
    该方法创建一个具有可变数量参数的新数组实例,而不考虑参数的数量或类型。
    语法:Array.of(element0[, element1[, ...[, elementN]]])
    参数:
    elementN 任意个参数,将按顺序成为返回数组中的元素。
Array.of(7);       // [7]
Array.of(1, 2, 3); // [1, 2, 3]

Array(7);          // [ , , , , , , ]
Array(1, 2, 3);    // [1, 2, 3]

Array.of(1);         // [1]
Array.of(1, 2, 3);   // [1, 2, 3]
Array.of(undefined); // [undefined]

该方法和 Array 构造函数之间的区别在于处理整数参数:Array.of(7) 表示创建一个具有单个元素 7 的数组,而Array(7)
表示创建一个长度为7的空数组(注意:这是指一个有7个空位(empty)的数组,而不是由7个undefined组成的数组)。

  • Array.prototype.find()
    该方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
    语法:arr.find(callback,[thisArg])
    参数:
    callback 在数组每一项上执行的函数,接收3个参数:

    • tem 当前遍历到的元素。
    • index 可选 当前遍历到的索引。
    • array 可选 数组本身。
      thisArg 可选 执行回调时用作this 的对象。
  • Array.prototype.findIndex()
    该方法找到一个元素在数组中的位置,返回数组中满足提供的测试函数的第一个元素的索引。若没有找到对应元素则返回-1。
    语法:arr.findIndex(callback[, thisArg])
    参数:
    callback 在数组每一项上执行的函数,接收3个参数:

    • tem 当前遍历到的元素。
    • index 可选 当前遍历到的索引。
    • array 可选 数组本身。
      thisArg 可选 执行回调时用作this 的对象。
//查找等于2的元素
let arr = [10,8,3,2,4,2,5];
//find方法返回第一个满足条件的元素或者undefined
let resultNum = arr.find((item, index) => {
  return item === 2;
});
console.log(resultNum);//2
// findIndex返回第一个满足条件的元素的索引或者-1
let resultIdx = arr.findIndex((item, index) => {
  return item === 2;
});
console.log(resultIdx);//3
function isPrime(element, index, array) {
	let start = 2;
	while (start <= Math.sqrt(element)) {
		if (element % start++ < 1) {
			return false;
		}
	}
	return element > 1;
}

console.log([4, 6, 8, 12].findIndex(isPrime)); // -1, not found
console.log([4, 6, 7, 12].findIndex(isPrime)); // 2
  • Array.prototype.includes()
    该方法找到一个元素是否存在于数组中,用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回 true,否则返回false。使用 includes()比较字符串和字符时是区分大小写。
    语法:arr.includes(valueToFind,[ fromIndex])
    参数:
    • valueToFind 需要查找的元素值。
    • fromIndex 可选 从fromIndex 索引处开始查找 valueToFind。如果为负值,则按升序从 array.length + fromIndex 的索引开始搜 (即使从末尾开始往前跳 fromIndex 的绝对值个索引,然后往后搜寻)。默认为 0。如果 fromIndex 大于等于数组的长度,则会返回 false,且该数组不会被搜索。
      返回值:
      返回一个布尔值 Boolean ,如果在数组中找到了(如果传入了 fromIndex ,表示在 fromIndex 指定的索引范围中找到了)则返回 true 。
[1, 2, 3].includes(2);     // true
[1, 2, 3].includes(4);     // false
[1, 2, 3].includes(3, 3);  // false
[1, 2, 3].includes(3, -1); // true
[1, 2, NaN].includes(NaN); // true
  • Array.prototype.fill()
    该方法用来填充数组,用一个固定值填充一个数组中从起始索引到终止索引内的全部元素。不包括终止索引。
    语法:
    arr.fill(value[, start[, end]])
    参数:
    • value 用来填充数组元素的值。
    • start 可选 起始索引,默认值为0。
    • end 可选 终止索引,默认值为 this.length。
      如果 start和end 是个负数, 则开始索引会被自动计算成为 length+start
[1, 2, 3].fill(4);  // [4, 4, 4]
[1, 2, 3].fill(4, 1);  // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2);  // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1);  // [1, 2, 3]
[1, 2, 3].fill(4, 3, 3);  // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2);  // [4, 2, 3]
  • Array.prototype.keys()
    该方法获取数组key,返回一个包含数组中每个索引键的Array Iterator对象。
    语法:arr.keys()
let arr = ["a", , "c"];
let sparseKeys = Object.keys(arr);
let denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2']
console.log(denseKeys);  // [0, 1, 2]
let arr = [2, 3, 4, 5, 6, 2];
// 遍历
let keys = arr.keys();
console.log(keys);
//keys变量当前是迭代器对象

// 遍历迭代器对象
let result;
while (!(result = keys.next()).done) {
  console.log(result);
}

/* console.log(keys.next());// { value: 0, done: false }
console.log(keys.next());// { value: 0, done: false }
console.log(keys.next());
console.log(keys.next());
console.log(keys.next());
console.log(keys.next());
console.log(keys.next());//{ value: undefined, done: true }
console.log(keys.next());//{ value: undefined, done: true } */

// 迭代器实现了Iterator接口,只要有实现了Iterator接口就可以for-of遍历
for (let key of keys) {
  console.log(key);
}
  • Array.prototype.values()
    Array.prototype.values()方法获取数组元素,返回一个新的 Array Iterator 对象,该对象包含数组每个索引的值。
    语法:arr.values()
let arr = ['w', 'y', 'k', 'o', 'p'];
let eArr = arr.values();

for (let letter of eArr) {
	console.log(letter);
} 
//"w" "y "k" "o" "p"
  • Array.prototype.entries()
    该方法获取数组中的key、value键值对,返回一个新的Array Iterator对象,该对象包含数组中每个索引的键/值对。
    语法:arr.entries()
    一个新的 Array 迭代器对象。Array Iterator是对象,它的原型(proto:Array Iterator)上有一个next方法,可用用于遍历迭代器取得原数组的[key,value]。
let arr = ["a", "b", "c"];
let iterator = arr.entries();
console.log(iterator);
// 打印出:Array Iterator {  }
for (let letter of iterator) {
	console.log(letter);
} 
// 打印出:
// Array [ 0, "a" ]
// Array [ 1, "b" ]
// Array [ 2, "c" ]
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-09 12:31:32  更:2022-05-09 12:31:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:21:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码