美文网首页
ES6经验总结

ES6经验总结

作者: 晚饭总吃撑 | 来源:发表于2020-09-01 10:57 被阅读0次

    我是从使用react开始在实际项目中使用es6语法的,转眼间已经过去了两年,中间从react到react-native再到node,es6有些语法确实方便很多,但是对其仅限于能用,了解的并不深入,所以想写篇笔记,记录下对es6语法的新认识,希望自己能够持续更新,不断进步。

    为什么叫ES6

    ES2015特指在2015年发布的新一代JS语言标准,ES6泛指下一代JS语言标准,包含ES2015、ES2016、ES2017、ES2018等。现阶段在绝大部分场景下,ES2015默认等同ES6。ES5泛指上一代语言标准。ES2015可以理解为ES5和ES6的时间分界线。

    babel

    之前在使用react的时候,webpack总是需要使用babel,babel的作用是编译es6,把es6编译成es5。就像java文件需要编译成class才能在电脑上运行,stylus、sass、less等css预处理需要编译成css才能在浏览器中运行,es6也一样,他不能直接在浏览器中执行,有些浏览器并不支持es6语法,所以需要使用babel将es6语法的代码转译成es5才能在浏览器中执行。

    let与var

    在ES6之前,声明变量只能用var,var方式声明变量其实是很不合理的,准确的说,是因为ES5里面没有块级作用域,let 声明的变量拥有自己的块级作用域,且修复了var声明变量带来的变量提升问题。

    字符串includes方法

    ES6在String原型上新增了includes()方法,用于取代传统的只能用indexOf查找包含字符的方法,indexOf返回-1表示没查到不如includes方法返回false更明确,语义更清晰

    箭头函数的this指向

    在使用react时,最开始声明对象方法是直接声明函数

    class App extends Component{
      testHandle(){
        this.setState({})
      }
      render(){
        return <Fragment>
          <div
              onClick={this.testHandle}
          >这里是测试</div>
        </Fragment>
      }
    }
    

    上面的代码中testHandle中的this在调用时是undefined,解决办法有三种
    第一种

    class App extends Component{
      testHandle(){
        this.setState({})
      }
      render(){
        return <Fragment>
          <div
              onClick={this.testHandle.bind(this)}
          >这里是测试</div>
        </Fragment>
      }
    }
    

    可以通过bind方法改变函数中this指向,只不过每次使用都得bind,非常繁琐
    第二种

    class App extends Component{
      constructor(props){
        super(props)
        this.testHandle = this.testHandle.bind(this);
      }
      testHandle(){
        this.setState({})
      }
      render(){
        return <Fragment>
          <div
              onClick={this.testHandle}
          >这里是测试</div>
        </Fragment>
      }
    }
    

    第二种是在构造函数constructor中bind一次,之后使用的时候就不用再bind了,这种方式比第二种方式简单了不少
    第三种

    class App extends Component{
      testHandle = ()=>{
        this.setState({})
      }
      render(){
        return <Fragment>
          <div
              onClick={this.testHandle}
          >这里是测试</div>
        </Fragment>
      }
    }
    

    第三种是使用箭头函数去声明,我之前的理解是这种声明方式是先声明类的一个属性testHandle在把函数赋值给该属性,因为该属性是类的所以函数中的this就永远指向this,但是今天看到关于箭头函数的一个定义
    箭头函数内的this指向的是函数定义时所在的对象,而不是函数执行时所在的对象
    也就是说在定义时,他的this指向谁,之后调用的时候就指向谁,这种方式也是最方便的方式,原因是箭头函数没有this,他的this是在他声明的时候确认的且一旦确认就不可改变

    ES6的箭头函数优化了这一点,它的内部没有自己的this,这也就导致了this总是指向上一层的this,如果上一层还是箭头函数,则继续向上指,直到指向到有自己this的函数为止,并作为自己的this;

    箭头函数不能用作构造函数,因为它没有自己的this,无法实例化;

    也是因为箭头函数没有自己的this,所以箭头函数 内也不存在arguments对象。

    ES6数组扁平化

    ES6提供了Array.flat()方法实现数组扁平化,他接受一个参数,可以是数字或者是Infinity,代表扁平化到第几个维度,适用于多维数组,默认值为1,该方法会移除数组中的空项

    var arr1 = [1, 2, [3, 4]];
    arr1.flat(); 
    // [1, 2, 3, 4]
     
    var arr2 = [1, 2, [3, 4, [5, 6]]];
    arr2.flat();
    // [1, 2, 3, 4, [5, 6]]
     
    var arr3 = [1, 2, [3, 4, [5, 6]]];
    arr3.flat(2);
    // [1, 2, 3, 4, 5, 6]
     
    //使用 Infinity 作为深度,展开任意深度的嵌套数组
    arr3.flat(Infinity); 
    // [1, 2, 3, 4, 5, 6]
    
    var arr4 = [1, 2, , 4, 5];
    arr4.flat();
    // [1, 2, 4, 5] 空项被移除
    

    对象合并Object.assign()

    之前在使用jquery封装插件的时候经常使用$.extend()方法合并对象,ES6中提供了合并对象的方法Object.assign(),他的使用方法和$.extend()的使用方法是一样的,都是传入多个对象,然后后面的对象向前面的对象合并,有冲突的属性会覆盖

    const target = { a: 1, b: 1 };
    
    const source1 = { b: 2, c: 2 };
    const source2 = { c: 3 };
    
    Object.assign(target, source1, source2);
    console.log(target) // {a:1, b:2, c:3}
    

    遍历数组与对象

    1、forEach
    forEach方法他接收三个参数分别为value、index、arr,分别代表:值,索引,遍历的数组
    (1)该方法只能遍历数组,不能遍历对象
    (2)该方法没有返回值
    (3) 该方法不能通过break和continue的方式停止循环及跳过当次循环

    let arr = [1,2,3,4,5]
    let result = arr.forEach((value,index,arr)=>{
        console.log(value) //值
        console.log(index) //索引
        console.log(arr) //原数据[1,2,3,4,5]
    })
    console.log(result) //undefined
    

    2、map
    map()方法他也是接受三个参数分别为value、key、obj,分别代表:值,键,遍历的对象
    (1)该方法只能遍历数组,不能遍历对象
    (2)该方法有返回值
    (3) 该方法不能通过break和continue的方式停止循环及跳过当次循环

    let arr = [1,2,3,4,5]
    let result = arr.map((value,index,obj)=>{
        console.log(value) //值
        console.log(index) //索引
        console.log(obj) //原数据[1,2,3,4,5]
        return value
    })
    console.log(result) //[1,2,3,4,5]
    

    3、for in
    (1)该方法既可以遍历数组,也可以遍历对象
    (2)该方法可以通过break和continue的方式停止循环及跳过当次循环

    const arr = ["a","b",1,true]
    for (const index in arr) {
          const value = arr[index]
          console.log(value)
    }
    let obj = {"a":1,"b":2,"c":3,"d":4}
    for (const key in obj) {
        const item = obj[key]
        if(key == "b"){
            break
        }
        console.log(key)
    }
    

    4、Object.keys(),Object.values()
    这两个方法对数组及对象都有作用,Object.keys()返回数组的索引或者对象的属性,Object.values()返回数组的值或者对象的值

            const arr = ["a","b",1,true]
            let obj = {"a":1,"b":2,"c":3,"d":4}
            console.log(Object.keys(arr)) //["0","1","2","3"]
            console.log(Object.values(arr)) //["a","b",1,true]
            console.log(Object.keys(obj)) //["a","b","c","d"]
            console.log(Object.values(obj)) //["a","b","c","d"]
    
            Object.keys(obj).forEach(key=>{
                let item = obj[key]
            })
    

    Promise的执行顺序

    promise是异步回调地狱的解决方案,大体的实现形式如下

    const  request = new Promise((resolve,reject)=>{
        axios({
            method: 'post',
            url: '/user/12345',
            data: {
              firstName: 'Fred',
              lastName: 'Flintstone'
            }
        }).then((res)=>{
          resolve(res)
        }).catch((error)=>{
          reject(error)
        })
    })
    request().then((res)=>{
      console.log(res)
    }).catch((error)=>{
      console.log(res)
    })
    

    resolve执行成功的回调,reject执行失败的回调,在的执行顺序上:Promise的回调函数是同步执行的,而Promise的链式调用then和catch方法是异步执行的

    new Promise(resolve=>{
      console.log(1)
      resolve(3)
    }).then(num=>{
      console.log(num)
    })
    console.log(2)
    

    上面的代码最后输出的结果是123,首先Promise回调函数是同步执行的,所以console.log(1)会首先执行,然后then是异步执行,所以先执行console.log(2),最后执行console.log(num),num是resolve(3)穿的参数,所以是3
    参考资料:
    https://mp.weixin.qq.com/s/aiG3eackQShKhwleVlhwww

    相关文章

      网友评论

          本文标题:ES6经验总结

          本文链接:https://www.haomeiwen.com/subject/otwmsktx.html