欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【NodeJS】ES6的基础语法

程序员文章站 2022-07-16 20:05:57
...

ES6的基础语法

一. let和const的认识

let关键字:

  • ES6新增的命令,用来声明变量。用法和var相似,但let所声明的变量只在let命令所在的代码块内有效
```js
{
    let a = 5;
    var b = 10;
}

console.log(a); // ReferenceError: a is not defined
console.log(b); // 10
```
  • 在同一块级作用域内不允许重复声明,不存在变量提升

    // 不存在变量提升会报错
    console.log(num);
    let num = 10;
    
    // 在同一块级作用域内不能重复声明,会报错
    let num = 10;
    let num = 30;
    
  • 有块级作用域

    for(let i = 0;i<=5;i++){
        // 不报错
        console.log(i);// 0 1 2 3 4 5
    }
    // 报错只能在声明的代码块内有效
    console.log(i); // ReferenceError: i is not defined
    
    • 很适合在for循环中使用
  • 有暂时性死区: 只要在块级作用域内存在let命令,他所声明的变量就”绑定“这个区域,不再受外部影响

    if (true) {
        // num = '一二三'; // ReferenceError
        // console.log(num); // ReferenceError
        let num;
        console.log(num); // undefined
        num = '四五六'
        console.log(num); // 四五六
    }
    

    在代码块内,使用let声明变量之前,该变量都是不可用的

  • **注意:**ES6 明确规定,如果区块中存在letconst命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

  • var和let的区别:

    • var:
      • 有变量提升
      • 没有块级作用域,是函数作用域
      • 可以重复声明
      • 可以重新赋值
    • let:
      • 没有变量提升
      • 有块级作用域
      • 不能重复声明
      • 可以重新赋值

const关键字

  • 声明一个只读的常量。一旦声明,常量的值就不能改变. const只声明不赋值会报错

    const num; // SyntaxError: Missing initializer in const declaration
    
    • 一旦声明就必须立即初始化,不能留到以后赋值。
    const num = 10086;
    
  • const作用域和let一样,只在声明所在的块级作用域内有效

    if(true){
        const num = 666;
        console.log(num); // 666
    }
    
    console.log(num); // ReferenceError: num is not defined
    
  • 不存在变量提升,不可重复声明

    // 不能重复声明
    const num = 100;
    const num = 200; // SyntaxError: Identifier 'num' has already been declared
    
    // 不存在变量提升
    console.log(str); // ReferenceError: Cannot access 'str' before initialization
    const str = 'hello';
    
  • 有暂时性死区

    if(true){
        // console.log(num); // ReferenceError
        const num = 666;
        console.log(num); // 666
    }
    
  • 扩展:ES6声明变量有六种方法: var、function、let、const、import、class

二. 变量解构赋值

1. 对象解构赋值

  • 取对象中属性的值,赋值给变量

    // 当变量名和对象属性名不一致
    let {name:username,age:userage} = {name:'李四',age:16}
    console.log(username,userage); // 李四 16
    
    // 当变量名和对象属性名一致
    let {name:name,age:age} = {name:'zhangsan',age:28}
    console.log(name,age); //张三 28
    
    // 当变量名和对象属性名一致时简化写法
    let {name,age} = {name:'张三',age:28}
    console.log(name,age); //张三 28
    
  • 对象解构只要属性名和变量名一致就能取得值,次序不一致没影响

    let cat = {
        name: '狸花猫',
        age: 2,
        color: '黑色'
    }
    
    // 次序不一致没影响
    let { color, age, name } = cat
    console.log(name, age, color); // 狸花猫 2 黑色
    
  • 可以将现有对象的方法,赋值到某个变量。

    const {log} = console;
    log('hello'); // hello
    

    把console的log赋值给log变量

    const { log:look } = console;
    look('hello'); // hello
    

    可以自定义

  • 如果变量取不到值,就等于undefined

    let {color}={name:'yahaha',age:2};
    console.log(color); // undefined
    
  • 可以用于嵌套结构的对象

    let obj ={
        dog:[
            '汪汪',
            {x : '叫'}
        ]
    };
    
    let {dog:[a,{x}]} = obj;
    console.log(a,x); // 汪汪 叫
    
    // 如果dog也要作为变量赋值
    let{dog,dog:[a,{x}]} = obj;
    console.log(a, x, dog); // 汪汪 叫 [ '汪汪', { x: '叫' } ]
    
  • 剩余符号…,表示取所有剩下的. 只能在最后一个变量前使用

    let obj = {
    	name: '某某某',
        age: 18,
    score: 0.5,
        like: '听音乐'  
    }
    
    let {name,...obj2} = obj;
    console.log(name,obj2); // 某某某 { age: 18, score: 0.5, like: '听音乐' }
    
    let {name,like,...obj2} = obj;
    console.log(name,obj2); // 某某某 听音乐 { age: 18, score: 0.5}
    
  • 可以指定默认值

    let {color='red',name,age}={name:'yahaha',age:2};
    console.log(name, age, color); // yahaha 2 red
    

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

    let {color = 'black'} = {color:undefined};
    console.log(color); // black
    
    let { num = 3 } = { num: null };
    console.log(num); // null
    
    • 如果有默认值的情况
    let obj = {
        name:'李白' ,
        age:20
    }
    
    let {age=10,name} = obj;
    console.log(name,age); // 李白 20
    

    相当于let { age: age = 10, name:name } = obj;用obj里age属性的值对变量age重新赋值,所以值是20

  • 总结: 对象解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。

2. 数组解构赋值

  • 从数组中提取值,按照对应位置,对变量赋值。

    let arr = [1,2,3];
    
    let [a,b,c] = arr;
    console.log(a,b,c); // 1 2 3
    
    
- 可以只匹配一部分值

    ```js
    let arr = [1,2,3];
    
    let [a,,] = arr;
    console.log(a); // 1
    
    let [,b,] = arr;
    console.log(b); // 2
    
    let [,,c] = arr;
    console.log(c); // 3
    
    let [a , , c] = arr;
    console.log(a, c); // 1 3
    
    let [a, , , , , f] = [1,2,3,4,5,6];
    console.log(a, f); // 1 6
    
    let [, , ,d , , f] = [1,2,3,4,5,6];
    console.log(d, f); // 4 6
  • 默认值

    let arr = [1,2,3];
    
    let [a,b,c,d=50] = arr;
    console.log(a,b,c,d); // 1 2 3 50
    
    let [a=10, b, c] = arr;
    console.log(a, b, c); // 1 2 3
    
  • 剩余符号…,表剩下的全要.只能在最后一个变量前使用

    let [a, ...b] = [1, 2, 3,4,5,6]
    console.log(b); // 2 3 4 5 6
    
    let [a, ...b, c] = [1, 2, 3,4,5,6]
    console.log(b); // SyntaxError: Rest element must be last element
    

3. 字符串的解构赋值

let [a,b,c,d,e] = 'hello';
console.log(a,b,c,d,e); // h e l l o
let {length:len} = 'hello';
console.log(len); // 5

因为类似数组所以有length属性,可以对这个属性结构赋值

4. 解构赋值结合函数声明

  • 声明一个函数,有多个形参

    function test({name,age,color}){
    	console.log(name,age,color)
    }
    
    test({
        name:'二哈',
        age:3,
        color:'黑色'
    }); // 二哈 3 黑色
    
  • 默认值

    function test({name,age,color='黑色'}){
    	console.log(name,age,color)
    }
    
    test({
    	name:'二哈',
        age:3
    }); // 二哈 3 黑色
    
    test({
    	name:'二哈',
        age:3,
        color:'白色'
    }); // 二哈 3 白色
    

三. 箭头函数

  • 是密名函数的一个简写

    // 普通的密名函数
    let fn = function(name){
        console.log('你的名字是:'+name);
    }
    
    // 箭头函数
    let fn = name => console.log('你的名字是:' + name);
    
    fn('张三');
    
  • 简写规则:

    1. function改成=>, =>可以理解成goes to
    2. 如果只有一个形参,那就可以省略形参小括号
    3. 如果不是一个形参,0个或者多个形参,那就不能省略这个形参小括号了
    4. 如果函数体只有一句话, 那就可以省略函数体的大括号
    5. 如果函数体只有一句话, 并且这一句话是return 返回值,那return也要省略
    6. 如果函数体不是一句话, 那就不能省略这个大括号
    • 例子

      /*
      let fn = function(str){
          return str+'World';
      }
      */
      
      // 箭头函数
      let fn = str => str + 'World';
      
      console.log(fn('Hello')); // HelloWorld
      
      // let fn = function(num1,num2){
      //     console.log(num1+num2);
      //     return num1+num2+63;
      // }
      
      // 箭头函数
      let fn = (num1, num2) => {
          console.log(num1 + num2);
          return num1 + num2 + 63;
      }
      
      console.log(fn(1,2)); // 3 66
      
  • 箭头函数的this

    1. 箭头函数的this和我们原来的那些个普通函数的this指向确实是不一样的.
    2. 箭头 函数的this指向谁? 由箭头函数的上下文环境决定的
    3. 箭头函数的this指向的原理。
      • 把箭头函数上下文环境的this用_this来保存 了,那箭头函数中用的this其实就是_this.
    4. 箭头函数使用注意:
      • 不是什么时候都要去使用箭头函数,就像下面这个dom操作使用箭头函数就不方便.
      • 不要用new关键字去调用箭头函数.
        <input type="button" value="按钮按钮" class="btn">
        <script>
            var btn = document.getElementsByClassName('btn')[0];
            // btn.onclick = function(){
            //     console.log(this.value); // 按钮按钮
            // }
    		// 箭头函数
            // btn.onclick = () => console.log(this.value); // undefined
    
            
            // btn.addEventListener('click',function(){
            //     console.log(this.value); // 按钮按钮
            // })
    		// 箭头函数
            // btn.addEventListener('click',() => console.log(this.value)); // undefined
    
    
            $('.btn').click(function () {
                console.log(this.value); // 按钮按钮
            })
    		// 箭头函数
            $('.btn').click(() => console.log(this.value));  // undefined
        </script>
    

    箭头函数的this和普通函数的this指向是不一样的

    • 箭头函数的this是由上下文环境决定的

      let obj1 = {
          name:'呀哈哈',
          sayHi:function(){
              console.log('1你好obj1我叫'+this.name);
      
              setTimeout(function () {
                  console.log('2你好obj1我叫' + this.name)
              }, 1000);
          }
      }
      
      let obj2 = {
          name: '张三',
          sayHi: function () {
              console.log('1你好obj2我叫' + this.name);
              setTimeout(() => console.log('2你好obj2我叫' + this.name), 1000)
          }
      }
      
      obj1.sayHi();
      obj2.sayHi();
      

      obj1输出为: 1你好obj1我叫呀哈哈

      ​ 2你好obj1我叫undefined

      obj2输出为: 1你好obj2我叫张三

      ​ 2你好obj2我叫张三

    • 箭头函数this指向的原理

      let obj2 = {
          name: '张三',
          sayHi: function () {
              var _this = this
              console.log('1你好obj2我叫' + this.name);
              setTimeout(() => console.log('2你好obj2我叫' + _this.name), 1000)
          }
      }
      

      把箭头函数上下文环境的this用_this来保存了,那箭头函数中用的this其实就是_this

四. 数组和对象的扩展

1. 对象的简写

  • ES5写法

    let name = '张三'
    let age = 20
    let score = 100
    
    var obj = {
        name:name,
        age:age,
        score:score,
        show:function(){
            console.log(name,age);
        }
    };
    
    console.log(obj); // { name: '张三', age: 20, score: 100, show: [Function: show] }
    obj.show(); // 张三 20
    
  • ES6写法

    let obj2 = {
        name,
        age,
        score,
        show(){
            console.log(name, age);
        }
    }
    
    console.log(obj2); // { name: '张三', age: 20, score: 100, show: [Function: show] }
    obj2.show(); // 张三 20
    
    • 如果想新加属性
    let obj2 = {
        name,
        age,
        score,
        nianling:age,
        show(){
            console.log(name, age);
        }
    }
    
    console.log(obj2); 
    /*
    {
      name: '张三',
      age: 20,
      score: 100,
      nianling: 20,
      show: [Function: show]
    }
    */
    obj2.show(); // 张三 20
    

2. 展开运算符

  • 对象展开

    let person = {
        eat:'吃东西',
        run:'跑'
    }
    
    let student = {
        homework: '做作业',
        exam: '测试'
    }
    
    let zhangsan = {
        // 展开语法
        ...person,
        ...student,
        sex:'男'
    }
    
    console.log(zhangsan); 
    // 输出结果: { eat: '吃东西', run: '跑', homework: '做作业', exam: '测试', sex: '男' }
    
  • 数组展开

    let arr1 = [1,2,3]
    let arr2 = [...arr1,40,50,66]
    console.log(arr2); // [ 1, 2, 3, 40, 50, 66 ]
    
    let arr3 = [66,50,1,55,100,12]
    let arrMax = Math.max(...arr3);
    console.log(arrMax); // 100
    
    • 数组降维: 如把二维数组变为一维数组

      var arr = [[10,20],[30,40,50]]
      var arrNew = [];
      
      arr.forEach(v=>{
          arrNew.push(...v);
      })
      
      console.log(arrNew); // [ 10, 20, 30, 40, 50 ]
      
      var arr = [10,20,[30,40,50],60,70]
      var arrNew = [];
      
      arr.forEach(v=>{
          if(Array.isArray(v)){
              arrNew.push(...v);
          }else{
              arrNew.push(v);
          }
      })
      
      console.log(arrNew); // [ 10, 20, 30, 40, 50, 60, 70 ]
      
    • 数组去重: 把数组中重复的去掉

      var arr = [10,30,20,50,20,30,40,50,60];
      var arrNew = [];
      
      // 排序后判断
      arr.sort((a,b)=>{
          return a-b;
      })
      
      console.log(arr); // [10,20,20,30,30,40,50,50,60]
      
      arr.forEach((value,index)=>{
          if(value != arr[index+1]){
              arrNew.push(value)
          }
      })
      
      console.log(arrNew); // [ 10, 20, 30, 40, 50, 60 ]
      

      上面的就是先排序后判断

      var arr = [10,20,30,30,20,10,40,50,60];
      var arrNew = [];
      var obj = {};
      
      // 利用对象的属性不能重名
      arr.forEach(value=>{
          if(obj[value] == undefined){
              arrNew.push(value);
              obj[value] = 1;
          }
      })
      
      console.log(arrNew); // [ 10, 20, 30, 40, 50, 60 ]
      

      使用对象法: 利用对象的属性不能重名

    • 数组升维

      var arr = [
          {type:'电子产品',name:'iPhone',price: 8888},
          { type: '家具', name: '桌子', price: 50 },
          { type: '电子产品', name: '微波炉', price: 500 },
          { type: '家具', name: '凳子', price: 25 },
          { type: '家具', name: '床', price: 1200 },
          { type: '食品', name: '辣条', price: 99999 },
          { type: '电子产品', name: '电视', price: 6666 },
          { type: '食品', name: '馒头', price: 0.5 },
          { type: '食品', name: '老干妈', price: 6 },
          { type: '电子产品', name: '电脑', price: 10000 },
          { type: '电子产品', name: '手机', price: 4000 }
      ]
      
      var arrNew = [];
      var obj = {};
      
      arr.forEach(value=>{
          // 第一个判断存入第一次出现的类型
          if (obj[value.type] == undefined){
              arrNew.push({
                  type: value.type,
                  data:[value]
              })
              obj[value.type] = 1
          }else{ // 进了else说明不是第一次出现,追加进相同类型的data中
              arrNew.forEach((value2,index)=>{
                  // 判断是哪一类
                  if(value.type == value2.type){
                      // 追加进相应的类
                      arrNew[index].data.push(value)
                  }
              })
          }
      })
      
      console.log(arrNew);
      

五. 其他数据类型的拓展

一. 模板字符串

  • 会保留原样字符串格式,可以站位

    let author = '李白';
    let str = `
        静夜思
        \t${author}
        床前明月光,
        疑是地上霜.
    `;
        
    console.log(str);
    /*
    	静夜思
        	李白
        床前明月光,
        疑是地上霜.
    */
    
  • 例子

    let name = '张三', age = 66, sex = '男';
    console.log(`我叫${name},性别:${sex},年龄:${age}`); // 我叫张三,性别:男,年龄:66
    
    function show(){
        return '看书';
    }
    console.log(`我喜欢${show()}`); // 我喜欢看书
    

二. 补充数组的方法

  • forEach()方法:遍历数组,没返回值

    let arr = [10,20,30,40]
    
    arr.forEach((value,index)=>{
        console.log(`索引:${index},值:${value}`);
    })
    

    输出结果:

    索引:0,值:10

    索引:1,值:20

    索引:2,值:30

    索引:3,值:40

  • map()方法:遍历数组,有返回值

    let arr = [10,20,30,40]
    let arrNew = arr.map((value,index)=>{
        return value * value;
    })
    console.log(arrNew); // [ 100, 400, 900, 1600 ]
    
  • filter()方法:过滤器, 会返回一个符合条件的新数组

    let arr = [1,2,3,4,5,6,7,8,9,10]
    
    let newArr = arr.filter((value,index)=>{
        return value % 2 == 0; // 如果条件成立则返回
    })
    
    console.log(newArr); // [ 2, 4, 6, 8, 10 ]
    

六. set和map的使用

一. set本身是一个构造函数,用来生成 Set 数据结构

  • set可以接收一个数组作为参数,用来初始化

    let set1 = new Set([10,20,30,40,10,20,20,30,50])
    console.log(set1) // 得到的是set对象 Set { 10, 20, 30, 40, 50 }
    

    set不能存放重复的元素

  • 用数组展开和Array.from方法可以将 Set 结构转为数组

    数组展开方式

    let set1 = new Set([10,20,30,40,10,20,20,30,50])
    let arrNew = [...set1];
    console.log(arrNew); // [ 10, 20, 30, 40, 50 ]
    

    Array.from方法

    let set1 = new Set([10,20,30,40,10,20,20,30,50])
    let arrNew = Array.from(set1);
    console.log(arrNew); // [ 10, 20, 30, 40, 50 ]
    
  • 利用set做数组去重

    let arr = [10,10,20,20,30,40,10,10,50]
    let set = new Set(arr);
    let arrNew = [...set];
    
    console.log(arrNew);// [ 10, 20, 30, 40, 50 ]
    
    // 上面代码可简写成一句
    let arrNew1 = [...new Set(arr)]; 
    console.log(arrNew);// [ 10, 20, 30, 40, 50 ]
    
    • 也可以做字符串去重

      let str = [...new Set('aaabbbcccddddefg')].join('');
      console.log(str); // abcdefg
      
  • WeakSet

    • 结构与Set 类似,也是不重复的值的集合
    • 但是WeakSet 的成员只能是对象,而不能是其他类型的值
    • WeakSet 中的对象都是弱引用

二. map

  • ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键

  • map可以说是’值-值‘的对应

    let map = new Map();
    map.set(1,2); // 数字做键
    map.set(10,'hello');
    map.set(true,'world'); // 关键字做键
    map.set(null,'空');
    
    console.log(map); // Map { 1 => 2, 10 => 'hello', true => 'world', null => '空' }
    
  • map可以接收一个数组作为参数,该数组的成员是一个个表示键值对的数组

    let map = new Map([
        ['name','张三'],
        ['age',20]
    ])
    
    console.log(map); // Map { 'name' => '张三', 'age' => 20 }
    console.log(map.size); // 2
    console.log(map.has('name')); // true
    console.log(map.get('name')); // 张三
    map.set('name','李四');
    console.log(map.get('name')); // 李四
    
  • 对同一个键赋值多次,后面的会覆盖前面的

    let map = new Map();
    map.set(1,2); 
    map.set(1,'hello');
    
    
    console.log(map.get(1)); // hello
    
  • map的属性和方法

    • 属性

      size属性:返回 Map 结构的成员总数。

    • 方法

      1.set(key, value): 设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键。

      let map = new Map([
          ['name','张三'],
          ['age',20]
      ])
      
      map.set('name','李四');
      console.log(map.get('name')); // 李四
      

      2.get(key): 读取key对应的键值,如果找不到key,返回undefined

      let map = new Map([
          ['name','张三'],
          ['age',20]
      ])
      
      
      console.log(map.get('name')); // 张三
      console.log(map.get('age')); // 20
      

      3.has(key): 返回一个布尔值,表示某个键是否在当前 Map 对象之中。

      let map = new Map([
          ['name','张三'],
          ['age',20]
      ])
      
      console.log(map.has('name')); // true
      console.log(map.has('sex')); // false
      

      4.delete(key): 删除某个键,返回true。如果删除失败,返回false

      let map = new Map([
          ['name','张三'],
          ['age',20]
      ])
      
      map.delete('name');
      console.log(map.get('name')); // undefined
      

      5.clear(): 清除所有成员,没有返回值。

      let map = new Map([
          ['name','张三'],
          ['age',20]
      ])
      
      map.clear();
      console.log(map); // Map {}
      

ES6转成ES5

一个网站,可以自动转换成ES5: https://www.babeljs.cn/

相关标签: NodeJS Nodejs ES6