美文网首页
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