【ES6】函数的参数、Symbol数据类型、迭代器与生成器

简介: 【ES6】函数的参数、Symbol数据类型、迭代器与生成器

函数参数的默认值设置


在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特点


  1. Symbol的值是唯一的,用来解决命名冲突的问题2) Symbol值不能与其他数据进行运算


  1. 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接口。


  1. Array


  1. Arguments


  1. Set


  1. Map


  1. string


  1. TypedArray


  1. 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提供的一种异步编程解决方案。


注意:


  1. 生成器函数需要在function的后面加一个符号*


  1. 生成器函数可以通过yield关键字来控制函数的执行流程。

  2. 生成器函数的返回值是一个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);
     }


生成器函数的参数


  1. 正常传递参数

function * fun2 (args){
    console.log(args)
    yield '111';
    yield '222';
    yield '333';
}
// 正常传递参数
let iterator = fun2('AAA');
iterator.next();  //AAA


  1. 在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();
目录
相关文章
|
1月前
|
JavaScript 前端开发
ES6:什么是Symbol?
ES6:什么是Symbol?
27 1
|
1月前
ES6之Symbol
ES6之Symbol
|
1月前
|
JavaScript 前端开发 开发者
编程笔记 html5&css&js 071 JavaScript Symbol 数据类型
编程笔记 html5&css&js 071 JavaScript Symbol 数据类型
|
1月前
|
JavaScript 前端开发
|
1月前
|
JavaScript 前端开发 开发者
|
1月前
|
存储 JavaScript
ES6+新特性-Symbol与Set/Map数据结构
ES6 引入了三种新的数据结构:Symbol、Set和Map。Symbol是唯一且不可变的值,常用于定义对象的独特属性;Set存储不重复值,适合数组去重;Map则是键值对集合,键可为任意类型,提供了更灵活的存储方式。这些新数据结构提供了更高效的操作手段,分别解决了属性命名冲突、数据去重和复杂键值对存储的问题。示例展示了如何使用Symbol、Set和Map进行基本操作。
|
1月前
|
JavaScript
js开发:请解释什么是ES6的Symbol,以及它的用途。
ES6的Symbol数据类型创建唯一值,常用于对象属性键(防冲突)和私有属性。示例展示了如何创建及使用Symbol:即使描述相同,两个Symbol也不等;作为对象属性如`obj[symbol1] = &#39;value1&#39;`;也可作枚举值,如`Color.RED = Symbol(&#39;red&#39;)`。
|
1月前
|
JavaScript 前端开发
ES6之原始数据类型Symbol
ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它属于 JavaScript 语言的原生数据类型之一,其他数据类型是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、大整数(BigInt)、对象(Object)。Symbol的作用是创建一个不可变且唯一的标识符,可以用作对象属性的键。它可以用来解决属性名冲突的问题,避免命名冲突。
45 0
|
9月前
ES6: Symbol概念与用法举例
ES6: Symbol概念与用法举例
31 0