一.解构
1.数组的解构
// 基础类型解构
let [a,b,c] = [1,2,3];
console.log(a,b,c); // 1,2,3
// 数组对象解构
let [a,b,c] = [{name: 1},{name: 2}, {name: 3}];
console.log(a,b,c); // {name: 1},{name: 2}, {name: 3}
// ...解构
let [head,...tail] = [1,2,3,4];
console.log(head,tail);// 1, [2,3,4]
// 嵌套解构
let [a,[b],c] = [1,[2,3], 4];
console.log(a,b,c);// 1,2,4
// 解构不成功为undefined
let [a,b,c] = [1];
console.log(a,b,c);// 1, undefined ,undefined
// 解构默认赋值
let [a=1,b=2] = [3];
console.log(a,b);// 3, 2
复制代码
2.对象的解构
//对象属性解构
let {f1,f2} = {f1:'test1',f2:'test2'};
console.log(f1,f2);// test1,test2
// 可以不按照顺序,这是与数组解构与数组解构区别之一
let {f1,f2} = {f1:'test',f2:'test2'};
console.log(f1,f2);// test1,test2
// 解构对象命名
let {f1:rename,f2} = {f1:'test1',f2:'test2'};
console.log(rename,f2);// test1, test2
//嵌套解构
let {f1: {f11}} = {f1:{f11:'test11',f2:'test12'}}
console.log(f11);//test11
// 默认值
let {f1='test1',f2:rename = 'test2'} = {f1:'current1',f2:'current2'};
console.log(f1,rename);// current1,current2
复制代码
3.解构的原理是什么?
- 针对可以迭代对象的Iterator,通过遍历器按顺序获取对应的值进行赋值.
3.1 Interator是什么?
- Interator 是一种接口,为各种不一样的数据解构提供统一的访问机制,任何数据解构只要有interator接口,就能通过遍历操作,一次按顺序处理数据结构内所有成员,es6中的for of 的语句相当于遍历器,会在遍历数据结构的时候,自动寻找Iterator接口.
3.2 Interator 的作用
- 为各种数据解构提供统一的访问接口
- 使得数据解构能按次序排列处理
- 可以使用ES6最新命令 for of进行遍历
function generateIterator(array) {
let index = 0;
return {
next: () => index < array.length ? {
value: array[index++],
done: false
} : {
value: undefined,
done: true
}
};
}
const iterator = generateIterator([1,2,3]);
console.log(interator.next()); // 1
console.log(interator.next()); // 2
console.log(interator.next()); // 3
console.log(interator.next()); // undefined
复制代码
3.3 可迭代对象
-
可以迭代对象是Iterator接口的实现,这是ECMAScript 2015的补充,他不是内置或语法,而仅仅是协议,任何遵循改协议都能成为可迭代对象,可迭代对象得有2个协议,可以迭代协议和迭代器协议.
-
可迭代协议: 对象必须实现Iterator方法,即对象或其原型链上必须有一个名叫Symbol.iterator的属性,该属性的值为无参函数,函数返回迭代器协议.
-
迭代器协议:定义了标准的方式来产生一个有限或无限序列值,其要求必须实现一个next()方法,该方法返回对象done(boolean)和value属性.
3.4 实现一个for of 遍历的对象
- 自定义数据解构,只要拥有Iterator接口,并将其部署到自己的Symbol.iterator属性上,就可以成为可迭代对象,能被for of循环遍历.
const obj = {
count: 0,
[Symbol.iterator]: () = {
return {
next: () => {
obj++;
if(obj.count <= 10) {
return {
value: obj.count,
done: false
}
} else {
return {
value: undefined,
done: true
}
}
}
}
}
};
for (const item of obj) {
console.log(item);
}
//或者
const iterable = {
0:'a',
1:'b',
2:'c',
length: 3,
[Symbol.iterator]:Array.prototype[Symbol.iterator]
};
for (const item of iterable) {
console.log(item);
}
复制代码
二 .遍历
1.数组遍历
1.1 for、forEach、 for of
const list = [1,2,3,4,5,6,7,8];
// for
for (let i = 0; len = list.length; i< len; i++) {
if(list[i] === 5) {
break; // 1,2,3,4
// continue; // 1,2,3,4,6,7,8
}
console.log(list[i]);
}
// forEach
const list = [1,2,3,4,5,6,7,8];
list.forEach((item,index,arr) => {
if (item === 5) return;
console.log(index); // 0 1 2 3 4 6 7 8
console.log(item); // 1 2 3 4 6 7 8
});
for (const item of list) {
if (item === 5) {
break; // 1 2 3 4
// continue; // 1 2 3 4 6 7 8
}
}
复制代码
- 总结:
-
三个都是从左往右遍历数组
-
forEach 无法跳出循环,for和for of 可以使用break或者continue中断
-
for of 直接访问的是实际元素,for遍历数组索引,forEach回调函数参数更丰富, 元素、索引、原数组都可以直接获取
-
for of与for 如果数组中存在空的元素,同样会执行
1.2 filter、map
//filter
const list = [
{id: 1, name: '小一', age: 11},,
{id: 2, name: '小二', age: 12},
{id: 3, name: '小三', age: 13}
];
const reslist = list.filter(item => item.age === 11);
console.log(reslist); // {id: 1, name: '小一', age: 11}
// map
const newlist = list.map(item => item.id);
console.log(newlist); // [1,2,3]
复制代码
- 总结:
-
二个都会生成一个新的数组,不会改变原来数组
-
二个都会跳过空的元素
-
map会将回调函数的返回值组成一个新的数组,长度和原来数组一致
-
filter 会将回调函数条件的元素组成一个新的数组,长度与原来的不一致
-
map生成的新数组元素可以自定义
6.filter生成的数组元素不能自定义,与原来数组元素一致
1.3 some 、every
// some
const list = [1,2,3,4,5,6];
const newlist = list.some(item => item > 5);
console.log(newlist); // true
const everyList = list.every(item => item > 5);
console.log(newlist); // false
复制代码
总结:
- 2个都是用来做数组判断用的,都是返回一个布尔值,
- some:若数组中有一个元素满足条件都返回true,循环中断,所有元素不满足,则返回false
- every: 和some刚好相反,若是数组中有一个元素不满足条件,则返回false,循环中断,若是所有元素都满足,则返回true;
1.4 find、findIndex
const list = [
{id: 1, name: '小一', age: 11},
{id: 2, name: '小二', age: 12},
{id: 3, name: '小三', age: 13}
];
const result = list.find(item => item.id === 3);
console.log(result);// { id: 3, name: '小三', age: 13 }
const index = list.findIndex(item => item.id === 3);
console.log(index); // 2
复制代码
总结:
- find方法返回数组中满足callback函数的第一个元素的值,如果不存在返回undefined
- find 方法返回数组中所查找元素的下标,如果不存在返回-1;
- 2个都是用来查找数组元素
1.5 reduce、reduceRight
- reduce方法接收2个参数,第一个参数是回调函数(callback),第二个参数是初始值(initialValue);
// 计算对象数组中某一属性的总和
const list = [
{id: 1, name: '小一', age: 11},
{id: 2, name: '小二', age: 12},
{id: 3, name: '小三', age: 13}
];
const sum = list.reduce((a, item) => {
return a + item.id;
},0);
console.log(sum); // 6
复制代码
- reduceRight方法也是接收2个参数,第一个参数是回调函数(callback),第二个参数是初始值(initialValue);
array.reduceRight(function(total, currentValue, currentIndex, arr), initialValue)
- total 初始值,计算结束后的返回值
- currentValue 当前元素
- currendIndex 当前元素索引
- arr 当前元素所属的数组对象
// 计算数组中元素的总和
let arr = [0,1,2,3,4];
const result = arr.reduceRight((total,item,index,arr) => {
return total + item;
},0);
console.log(result); // 10
复制代码
2.对象遍历
2.1 for in
- 遍历数组时,key为数组下标字符串,遍历对象,key为对象字段名
let obj = {a: 'test1', b: 'test2'};
for (let key in obj) {
console.log(key,obj(key));
//a test1
// b test2
}
复制代码
缺点:
1.for in 不仅会遍历当前对象,还包括原型链上的可枚举属性
2.for in 不适合遍历数组,主要应用于对象
2.2 Object.keys
- 改方法返回一个给定对象的自身可枚举属性组成的数组
const obj = {a:1,b:2};
const keys = Object.keys(obj);// [a,b]
// 手动模拟Object.keys实现
function getObjectKeys(obj) {
const result = [];
for (const prop in obj) {
if(obj.hasOwnProperty(prop)) {
result.push(prop);
}
}
return result;
}
复制代码
2.3 Object.values
- 该方法返回一个给定对象自身的所有可枚举属性值的数组
const obj = {a:1,b:2};
const keys = Object.values(obj);// [1,2]
// 手动模拟Object.values实现
function getObjectValues(obj) {
const result = [];
for (const prop in obj) {
if(obj.hasOwnProperty(prop)) {
result.push(obj[prop]);
}
}
return result;
}
复制代码
2.4 Object.entries
- 该方法返回一个给定对象自身可枚举属性的键值对数组
const obj = {a:1,b:2};
const keys = Object.entries(obj);// [[‘a’,1],[‘b’,2]]
// 手动模拟Object.values实现
function getObjectEntries(obj) {
const result = [];
for (const prop in obj) {
if(obj.hasOwnProperty(prop)) {
result.push(prop,obj[prop]);
}
}
return result;
}
复制代码
2.5 Object.getOwnPropertyNames
- 该方法返回一个数组,该数组对元素是obj自身拥有的枚举或不可枚举属性名称字符串.
Object.prototype.aa = '1111';
const testData = {a: 1,b: 2 }
for (const key in testData) {
console.log(key);
}
console.log(Object.getOwnPropertyNames(testData));
//a
// b
// aa
// [ 'a', 'b' ]
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END