ES6 语法/应用

74 阅读4分钟

ES6,可以理解为JavaScript规范

const ,let

1. 不允许重复声明

  var arg1 = 'a';
  arg1 = 'b';
  ----------------如果想定义常量
  // -ES5
  Object.defineProperty(window, 'arg2',{
     value:'a',
     writable: false
  })
  //也可以修改getter,setter方法
  
  //ES6
  const arg2 = 'a';

2. 块级作用域 -- 解决变量覆盖问题

  if(true){
     var arg1 = 'a';
  }
  console.log(arg1); //可以打印a
  
  if(true){
     const arg1 = 'a';
  }
  外面访问不到arg1

es5如何实现let

let a=10;
{
  let a = 29
  console.log(a) //29
}
console.log(a) // 10
--------------编译成es5---------------
var a=10;
{
   var _a=29;
   console.log(_a);
}
console.log(a);

3. const定义的对象

能用const,都用const,可以保证对象地址不被轻易改变

// 会被改变的对象,到底用const还是let
const obj = {
   name:'',
   age:'18'
  }
obj.name = 'a';
 
// 栈,堆

const保证栈里的内容不会被改变,obj存在栈里的是指向堆的地址

  • 如何对一个对象进行常量化 -- Object.freeze()

    Object.freeze(obj);
    
  • 只能冻结根层

     const obj = {
       name:'',
       age:'18',
       course: {
          course1: '1',
          course2: '2'
       }
    }
    
    function deepFreeze(obj){
       Object.freeze(obj);
       (Object.keys(obj) || []).forEach(key => {
          if(typeof obj[key] === 'object){
              Object.freeze(Obj[key])
           }
       })
    }
    

4. var定义的变量,会挂到Windows上,let/const不会

解构

  1. 数组的解构 - 具备Iterator接口的数据结构,都可以使用数组的解构赋值
let [x, y, z] = new Set(['a', 'b', 'c']);
  1. 对象的解构
  • 和数组不同,数组的元素按次序排列,对象的属性没有次序,变量要和属性同名
  • 数组是特殊的对象,可以对数组进行对象属性解构
arr = [1,2,3]
let { 0: first, [arr.length - 1]: last } = arr;
first:1 last:3
  • 不能对 对象进行数组解构,会报错,因为对象默认不具备iterator接口 image.png
  1. 字符串可以数组解构,也可以对象解构

用途

  1. 交换变量的值
  2. 返回多个值
  3. 提取JSON对象中的数据
  4. 遍历map结构

解构的原理

调用遍历器方法,会返回一个迭代器对象,迭代器对象有一个next()方法,迭代器对象调用next()方法,就会返回value值

image.jpeg

Iterator遍历器

  • 为数据结构提供可以遍历访问的方法,for of循环就是使用Iterator接口
  • 默认接口部署在[Symbol.iterator]属性上,一个数据结构有这个属性,就认为它是可遍历的
  • Array, Set, Map, String, 函数arguments对象原生有Iterator接口

箭头函数

//传统函数
const add = (a, b) => {retrn a+ b;} //写{}必须有return
const add1 = (a,b) => a+b 

箭头函数的this

箭头函数没有独立上下文,没有自身的this,取决于外面的this,写代码时就确定,而不是执行时

class Obj{
   a =13;
   test = () => { console.log(this.a)}
}
const obj1 = new Obj();
obj2.fn = obj1.test;
obj2.fn() // this指向的都是obj1
obj3.fn = obj1.test;
boj3.fn() //this指向的都是obj1

image.png

需要上下文的场景

  1. dom操作callback的时候

    const btn = document.querySelector('#btn');
    btn.addEventListener('click', function(){
       this.style.color = '#fff';
    })
    
  2. 类操作的时候

    //箭头函数无法构造类
    function Obj(name, age){
       this.name = name;
       this.age = age;
    }
    

箭头函数的参数特性 - 没有arguments

class 类(基于函数的语法糖)

传统类型对象 - function

  function Course(teacher, course){
     this.teacher = teacher
     this.course = course
  }
  Course.prototype.getCourse = function(){
     return ...
   }
  const course1 = new Course('aa', 'ES')

ES6-class

  class Course{
     constructor(teacher, course){ //构造函数内部的逻辑
      this.teacher = teacher
      this.course = course
     }
     getTeacher(){ //实例的方法
        return ''
     }
     static getCourse(){} //挂在类上公用
  }

class继承

  class Person{
     constructor(name){
        this.name = name
     }
     printName(){
        console.log(this.name)
     }
  }
  class Student extends Person{
     constructor(name, course){
        super(name); // 执行父类构造函数
        this.course = course
     }
  }
  

class的类型是什么

Function => Object => null

建立只读变量

  class Course{
     let _course = 'aa'
     this.getcourse = () =>{ return _course }
  }

Map

键值对的集合

const map = new Map();
map.set('1', 2);
map.set({key: '1'}, 10);

和Object区别

  • object对象的key,字符串或symbol,如果用其他类型如数组作为key,也会调用toString转化为字符串
  • map的key可以是任何类型

Set

数值的集合,类似数组,但元素是不重复的--可以用于数组去重

const set = new Set();
const arr = [1,2,3,4,3,2,1];
const arrnew = [...new Set(arr)]

Generator函数

  • 生成器函数,会返回一个Generator对象,这个对象是可迭代的
  • 生成器函数执行时可以暂停,后面从暂停处继续执行
  1. 生成器函数
function* funGenerator(){
   yield 'a'
   yieldqa
}
  1. 获取Generator对象
const gen =  funGenerator();  这时函数还没有执行,只是获取对象
  1. 调用next()方法
gen.next() { value: yield之后的值, done: true/false 是否执行完毕}
gen.next().value --'a'
gen.next().value --'b'
  1. for of 可以获取到yield后面的所有值
for(const ite of gen){
  console.log(ite) -- 'a' 'b'
}
function* genfib(){
  console.log('gen开始执行');
  let a = 1;
  let b = 1;
  while(true){
     console.log('gen即将 yield');
     yield a
     console.log('gen yield返回');
     const t = b;
     b += a;
     a = t;
  }
}
const gen = genfib();
for(let i=0;i<5;i++){
   gen.next();
}