Es6学习笔记(2)

1.(…)拓展运算符

  • es6新增的扩展运算符...
  • 作用:
    • 所有能够被迭代的东西,都可以被展开运算符…,进行展开,即可将数组展开变成参数序列,将字符串展开变成单一的字符

代码展示:

// 『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』
//声明一个数组 ...
const tfboys = ['易烊千玺','王源','王俊凯'];
// => '易烊千玺','王源','王俊凯'

// 声明一个函数
function chunwan(){
console.log(arguments);
}
chunwan(tfboys);//结果只有一个参数,即一个数组
chunwan(...tfboys);//结果有三个参数,相当于转换成chunwan('易烊千玺','王源','王俊凯')

结果展示:

image

拓展运算符的应用:

代码展示:

//1. 数组的合并:相当于把每一个目标数组变成对应的参数序列,然后再传进新数组里面
const kuaizi = ['王太利','肖央'];
const fenghuang = ['曾毅','玲花'];
// es5的数组合并方法:数组1.concat(数组2) = 数组[1 + 2]
// const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
console.log(zuixuanxiaopingguo);

//2. 数组的克隆
const sanzhihua = ['E','G','M'];
const sanyecao = [...sanzhihua];// ['E','G','M']
console.log(sanyecao);

//3. 将伪数组转为真正的数组
const divs = document.querySelectorAll('div');
const divArr = [...divs];
console.log(divArr);// arguments

结果展示:

image

2.rest形参的默认值(代替arguments)

  • arguments参数的复习:
    • 在每一个函数内,都有一个内置的数组,是一个变量,叫做argumentsarguments可以存储当前函数传入的所有参数,而且,是通过传参的顺序,进行排列的
  • rest参数导读:
    • ES6中引入rest参数(形式为’…变量名’),用于获取函数的多余参数。rest参数之后不能再有其他参数(即只能是最后一个参数)。

代码展示:

// ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
// ES5 获取实参的方式
function date(){
console.log(arguments);
}
date('白芷','阿娇','思慧');

// rest 参数
function date(...args){
console.log(args);// filter some every map
}
date('阿娇','柏芝','思慧');

// rest 参数必须要放到参数最后
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6);

结果展示:

image

3.promise的使用翻阅前面的博客

4.symbol新数据类型

  • ES6 引入了一种新的原始数据类型 Symbol, 表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型
  • Symbol 特点
    • 1)Symbol 的值是唯一的,用来解决命名冲突的问题
    • 2)Symbol 值不能与其他数据进行运算
    • 3)Symbol 定义的对象属性不能使用 for…in 循环遍历, 但是可以使用Reflect.ownKeys 来获取对象的所有键名

代码展示

//创建Symbol
let s = Symbol();
console.log(s, typeof s);

let s2 = Symbol('五邑大学');//创建symbol时,我们可以给其添加一个字符串描述
let s3 = Symbol('五邑大学');
console.log(s2 === s3);//false,唯一性,symbol只是代表标志,即通过这种方创建的symbol值是相对独立的,每一个都不一样

//Symbol.for 创建(函数对象),通过这种方法创建的symbol是唯一的symbol值(根据括号内的字符串对应唯一的symbol值)
let s4 = Symbol.for('五邑大学');
let s5 = Symbol.for('五邑大学');
console.log(s4 , typeof s4);//Symbol(五邑大学) 'symbol' , 同样也是symbol类型
console.log(s4 === s5);//true

//不能与其他数据进行运算和字符串的拼接
// let result = s + 100;
// let result = s > 100;
// let result = s + s;

// 总结以下我们学过的七种数据类型
// USONB you are so niubility
// u undefined
// s string symbol
// o object
// n null number
// b boolean

结果展示:

image

symbol的使用场景:

  • symbol由于它的唯一性,使用场景一般是给对象添加属性和方法
  • symbol参考手册(学习symbol的内置值)

代码展示

// 使用场景一:作为属性名symbol
// 由于每一个 Symbol 值都是不相等的,这意味着 Symbol 值可以作为标识符,用于对象的属性名,
// 就能保证不会出现同名的属性。这对于一个对象由多个模块构成的情况非常有用,能防止某一个键被不小心改写或覆盖
let mySymbol = Symbol('你好');
console.log(typeof mySymbol);

// 第一种写法
let b = {};
b[mySymbol] = 'Hello!';

// 注意,Symbol 值作为对象属性名时,不能用点运算符
console.log(b);//{Symbol(你好): 'Hello!'}
console.log(typeof b[mySymbol], b[mySymbol]);//string Hello!

// 第二种写法
let a = {
[mySymbol]: 'Hello!'
};
console.log(a);


// 使用场景二:作为对象的属性值添加到对象当中去
// Symbol 类型还可以用于定义一组常量,保证这组常量的值都是不相等的。
const log = {
DEBUG: Symbol('debug'),
INFO: Symbol('info'),
WARN: Symbol('warn')
};
console.log(log['DEBUG']);//Symbol(debug)

// 实际上的用法:就是为了给一些大型项目当中添加一些属性和方法,但是又怕原与对象当中的属性和方法冲突了,
// 所以可以用symbol来添加独一无二的属性和方法来解决属性名或方法名冲突的情况
// 给对象添加symbol属性
const s = Symbol();
log[s] = () => console.log('你好!');

console.log(log);//输出一个对象,里面包含添加的 ‘s’ symbol属性

结果展示:

image

4.iterator遍历器

  • 所谓迭代器,即遍历器(Iterator)就是一种机制。它是一种接口(这里的接口就是对象里的属性),为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
  • 1)ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费
  • 2)原生具备 iterator 接口的数据(可用 for of 遍历)
    • a)Array
    • b)Arguments
    • c)Set
    • d)Map
    • e)String
    • f)TypedArray
    • g)NodeList
  • 3)工作原理
    • a)创建一个指针对象,指向当前数据结构的起始位置
    • b)第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
    • c)接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
    • d)每调用 next 方法返回一个包含 value 和done 属性的对象注: 需要自定义遍历数据的时候,要想到迭代器。

代码展示:

const west = ['唐僧', '孙悟空', '沙僧', '猪八戒'];

// 用for....of循环遍历
for (let v of west) {
console.log(v);//唐僧 孙悟空 沙僧 猪八戒
// 由此可见,for of循环的v变量保存的是数组的键值
}

// 用for....in循环遍历
for (let v in west) {
console.log(v);//0 1 2 3
// 由此可见,for in循环的v变量保存的是数组的键名
}

// 为什么数组能够使用for of遍历呢??
// 只要对象里面有symbol,Iterator属性都能可以
console.log(west);//里面有:Symbol(Symbol.iterator): ƒ values(),这是一个方法(函数)

// 对symbol进行一个复习
// 这里调用一下这个函数(方法)
let iterator = west[Symbol.iterator]()
console.log(iterator);//里面有:next: ƒ next() , 这是一个方法(函数)

// 工作原理
// a) 创建一个指针对象,指向当前数据结构的起始位置
// b)第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
// c)接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
// d)每调用 next 方法返回一个包含 value 和done 属性的对象注: 需要自定义遍历数据的时候,要想到迭代器。

console.log(iterator.next());//{value: '唐僧', done: false}
console.log(iterator.next());//{value: '孙悟空', done: false}
console.log(iterator.next());//{value: '沙僧', done: false}
console.log(iterator.next());//{value: '猪八戒', done: false}
console.log(iterator.next());//{value: undefined, done: true}
// 解析:next每调用一次,都会返回新的值(指针一直向后移动,直到返回最后一个成员),
// 这里的done属性是度的一个完成时,这里表示是否遍历完成,false表示遍历未完成,true表示遍历完成

结果展示:

image

迭代器的应用:

  • 迭代器的应用多用于自定遍历数据,按照我们的意愿来遍历数据
    • a) 创建一个指针对象,指向当前数据结构的起始位置
    • b)第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
    • c)接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
    • d)每调用 next 方法返回一个包含 value 和done 属性的对象注: 需要自定义遍历数据的时候,要想到迭代器。

代码展示:

// 声明一个对象
const class1 = {
name:"终极一班",
member:[
'张三' ,
'李四' ,
'陈五'
],
//重点: 自定义遍历要求:使用迭代器和for of方法遍历上面对象中的数组,这里考察对迭代器工作原理的理解
// 首先创建指针对象
[Symbol.iterator](){
// 设置索引变量,用于后续索引数组元素
let i = 0;
// 这个Symbol.iterator方法的返回值需是一个对象
return {
// 设置next方法,这里用的是箭头函数创建方法,若是用function,需要将this向上一级嵌套,
// 即在[Symbol.iterator]()的外层嵌套一个_this = this,但是用箭头函数创建不用,因为它是静态的,
// 自动向外层寻找
next:() => {
// 这里就是常规的遍历循环
if(i < this.member.length){
// done是标志位,用于判断遍历是否完成
const result = {value:this.member[i] , done:false};
// 下标自增
i++;
// 返回结果
return result;
}
else{
return{value:undefined , done:true}//done:true 表示完成遍历
}
}
}
}


}
console.log(class1);

// 常规的数组遍历方法:forEach(),但是不符合面向对象的要求
// class1.member.forEach();

//重点: 自定义遍历要求:使用迭代器和for of方法遍历上面对象中的数组,这里考察对迭代器工作原理的理解
for(let v of class1){
console.log(v);
}

结果展示:

image