函数参数的默认值设置
在es6中给函数的默认值中设置初始值,一般设置了默认初始值的参数,需放在最后。
let fun = (a,b,c=15)=>{ return a+b+c; } let result = fun(1,2); console.log(result); //18
与解构赋值一起使用
info({ name:'suliang', age:21, qq_num:'787991021' }) function info({name,age,qq_num,address='787991021@qq.com'}){ console.log(name); //suliang console.log(age); //21 console.log(qq_num) //787991021 console.log(address); //787991021@qq.com }
rest参数
在es6中引入了rest参数(用...args
表示)来代替arguments来显示实参。
let fun1 = (...args)=>{ console.log(args); } fun1(1,2,3) //(3) [1, 2, 3]
返回的是一个数组对象。
注意:rest参数必须放在最后一个。
扩展运算符
扩展运算符...
可以将数组转换为以逗号分隔的参数序列。
let arr = ['xiaohu','gala','ming']; let fun = (...args) =>{ console.log(args); } fun(arr) //(1) [Array(3)] fun(...arr) //(3) ['xiaohu', 'gala', 'ming']
扩展运算符的应用
数组合并
let arr1 = ['xiaohu','gala','ming']; let arr2 = ['wei','breath']; //使用扩展运算符 const RNG = [...arr1,...arr2]; console.log(RNG); //(5) ['xiaohu', 'gala', 'ming', 'wei', 'breath'] //使用数组中的方法 console.log(arr1.concat(arr2)); (5) ['xiaohu', 'gala', 'ming', 'wei', 'breath']
数组复制
let arr = [1,2,3]; let arr_copy = [...arr]; console.log(arr_copy); //(3) [1, 2, 3]
将伪数组转换为真正的数组
在获取dom元素时,通常我们获取到一组元素,实际上就是一个伪数组。
<body> <p></p> <p></p> <p></p> // 3.将伪数组转换为真正的数组 <script> let ps = document.querySelectorAll('p'); console.log(ps); //NodeList(3) [p, p, p] 伪数组 let arr_ps = [...ps]; console.log(arr_ps); //(3) [p, p, p] </script> </body>
新的数据类型:symbol
ES6引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol特点
- Symbol的值是唯一的,用来解决命名冲突的问题2) Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用
Reflect.ownKeys来获取对象的所有键名
symbol的创建
let s1 = Symbol('su'); let s2 = Symbol('su'); console.log(s1==s2); //false let s3 = Symbol.for('su'); let s4 = Symbol.for('su'); console.log(s3 == s4); //true
使用symbol添加对象属性
let info ={ name:'su', age:21, Sayname:function(){ console.log(this.age); }, [Symbol('sayName')]:function(){ console.log(this.name); }, [Symbol('sayAge')]:function(){ console.log(this.age); } } const x = Object.getOwnPropertySymbols(info); info[x[0]](); //su info[x[1]](); //21
迭代器
迭代器(lterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。
- ES6创造了一种新的遍历命令
for...of
循环,lterator接口主要供for...of
消费 - 原生具备iterator接口的数据(可用
for...of
遍历)
以下对象都部署了Iterator接口。
- Array
- Arguments
- Set
- Map
- string
- TypedArray
- NodeList
实例:
在迭代器中,for...of
返回的是数值,而for...in
返回的是索引。
const arr=['ming','gala','xiaohu']; for(let x of arr){ console.log(x); //ming,gala,xiaohu }
实现原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针一直往后移动,直指向最后一个成员
- 每次调用next方法返回一个包含value和done属性的对象
如:
const arr =['ming','gala','xiaohu']; // 迭代器原理: let arr1 = arr[Symbol.iterator](); console.log(arr1.next()); //{value: 'ming', done: false} console.log(arr1.next()); //{value: 'gala', done: false} console.log(arr1.next()); //{value: 'xiaohu', done: false} console.log(arr1.next()); //{value: undefined, done: true}
迭代器的运用:自定义遍历数据
实例:
//案例一: let arr = { name:'su', info:[21,'787991021','csdn'], [Symbol.iterator](){ let index = 0; let _this = this; return { next:function(){ if(index < _this.info.length){ const result = {value:_this.info[index],done:false}; index ++ ; return result; }else{ return {value:undefined,done:true} }; } }; } } for(let x of arr){ console.log(x); } console.log('*****************************'); //案例二: let arr2 = { num:2, member:['xiaoming','gala','xiaohu','wei','breath'], //自定义迭代器 [Symbol.iterator](){ let index2 = 0; return { next:()=>{ if(index2< this.member.length){ const result2 = {value:this.member[index2],done:false}; index2 ++; return result2; }else{ return {value:undefined,done:true} }; } }; } }; for(let y of arr2){ console.log(y); }
通过迭代器的原理我们可以自定义包装一个Iterator接口。就可以使用for...of
进行遍历数据。
生成器
生成器是ES6中新增的一种函数控制、使用的方案,它可以让我们更加灵活的控制函数什么时候继续执行、暂停执行等。
生成器函数实际上是ES6提供的一种异步编程解决方案。
注意:
- 生成器函数需要在function的后面加一个符号
*
- 生成器函数可以通过
yield
关键字来控制函数的执行流程。 - 生成器函数的返回值是一个Generator(生成器)。
写一个生成器函数:
function * fun1(){ //通过yield来控制函数的执行流程 yield console.log('111'); yield console.log('222'); yield console.log('333'); } let iterator = fun1(); iterator.next(); //111 iterator.next(); //222 iterator.next(); //333 //遍历 for(let i of fun1()){ console.log(i); }
生成器函数的参数
- 正常传递参数
function * fun2 (args){ console.log(args) yield '111'; yield '222'; yield '333'; } // 正常传递参数 let iterator = fun2('AAA'); iterator.next(); //AAA
- 在next方法中传递参数
在next方法中传入实参,那么就会将该参数作为yield代码块的返回值。
function * fun2 (args){ console.log(args) let num1 = yield '111'; console.log(num1); let num2 = yield '222'; console.log(num2); let num3 = yield '333'; console.log(num3); } // 在next方法中传递参数 iterator.next(); iterator.next("BBB"); //BBB iterator.next('CCC'); //CCC iterator.next('DDD'); //DDD
生成器函数实例
要求:在1秒后输出111,2秒后输出222,3秒钟输出333
1.使用定时器来实现:
setTimeout(() => { console.log('111'); setTimeout(() => { console.log('222'); setTimeout(() => { console.log('333'); }, 3000); }, 2000); }, 1000);
2.使用生成器函数实现
function one (){ setTimeout(() => { console.log('111'); iterator.next(); }, 1000); } function two(){ setTimeout(() => { console.log('222'); iterator.next(); }, 2000); } function three (){ setTimeout(() => { console.log('333'); iterator.next(); },3000); } function * all(){ yield one(); yield two(); yield three(); } let iterator = all(); iterator.next();
要求:模拟生成用户数据,商品数据,订单数据
console.log('程序开始执行!'); function users(){ setTimeout(()=>{ let data = '用户数据'; //这里存放用户数据 iterator.next(data); },1000) } function order(){ setTimeout(() =>{ let data = '订单数据'; //这里存放订单数据 iterator.next(data); },1000) } function store(){ setTimeout(() => { let data = '商品数据'; //这里存放商品数据 iterator.next(data); }, 1000); } function * info(){ let re_users = yield users(); console.log(re_users); let re_order = yield order(); console.log(re_order); let re_store = yield store(); console.log(re_store); } let iterator = info(); iterator.next();