美文网首页
深入解读ES6

深入解读ES6

作者: 茕茕微凉 | 来源:发表于2019-04-02 23:46 被阅读0次

    ES6怎么来的

    • ECMAScript 和 JavaScript
      • ECMA 是标准,JS 是实现
      • ECMAScript 简称 ECMA 或 ES
    • 历史版本
      • 1996, ES1.0 Netscape 将 JS 提交给 ECMA 组织,ES 正式出现
      • 1999, ES3.0 被广泛支持
      • 2011, ES5.1 成为 ISO 国际标准
      • 2015, ES6.0 正式发布

    ES6兼容性

    • ES6(ES2015) 支持的环境 IE10+, Chrome, FireFox, 移动端, NodeJS

    • 解决不兼容办法,编译、转换

      • 在线转换
      • 提前编译(推荐)
    • Babel 中文网

      • Babel 入门教程 阮一峰
      • Babel 是一个 JavaScript 编译器,与browser.js是同一词
      • 一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行
      • 现在就用 ES6 编写程序,而不用担心现有环境是否支持

    变量 let 和 常量 const

    • var 的问题

      • 可以重复声明,没有报错和警告
      • 无法限制修改
      • 没有块级作用域,{ }
    • let 和 const

      • 不能重复声明
      • let 是变量,可以修改
      • const 是常量,不能修改
      • 都是块级作用域, { } 块内声明的,块外无效
    //重复声明
    var a = 12;
    var a = 5;
    alert(a);//执行弹出5,浏览器不报错不警告
    
    let a = 12;
    let a = 5;
    alert(a);//报错!
    
    //变量和常量
    let a = 12;
    a = 5;
    alert(a);//5
    
    const a = 12;
    a = 5;
    alert(a);//报错!
    
    //块级作用域
    {
      let a = 1;
      alert(a);//弹出1
    }
    alert (a);//报错!a is not defined
    
    • 块级作用域举例
      • 原来用 var 的方式,结果弹出的都是 3
      • 或者将变量 封装到函数里,限制作用域,但比较麻烦
      • 用 let 最简单,直接 var 改 let,解决作用域问题
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <script>
            window.onload= function () {
                /*
                var aBtn = document.getElementsByTagName('input')
                for (var i=0; i < aBtn.length; i++) {
                    aBtn[i].onclick = function () {
                        alert(i)//3
                    }
                }*/
                
                /*
                var aBtn = document.getElementsByTagName('input')
                for (var i = 0; i < aBtn.length; i++) {
                    // 封装到函数里,限制作用域
                    (function (i) {
                        aBtn[i].onclick = function () {
                            alert(i)
                        }
                    })(i)
                }*/
    
                var aBtn = document.getElementsByTagName('input')
                for (let i = 0; i < aBtn.length; i++) {
                    aBtn[i].onclick = function () {
                        alert(i)
                    }
                }
            }
        </script>
    </head>
    <body>
        <input type="button" value="按钮1">
        <input type="button" value="按钮2">
        <input type="button" value="按钮3">
    </body>
    </html>
    

    函数-箭头函数

    • 箭头函数,就是函数的简写
      • 如果只有一个参数,() 可以省
      • 如果只有一个return{}可以省
    • 修正this指向
    // 普通函数
    function name() {
    
    }
    
    // 箭头函数,去掉 function, 加上 =>
    () => {
    
    }
    
    let arr = [12,5,8,99,34,13];
    arr.sort(function (n1,n2){
      return n1-n2;
    });
    
    arr.sort((n1,n2) => {
      return n1-n2;
    })
    
    //如果只有一个参数,`()` 可以省
    //如果只有一个`return`,`{}`可以省
    let show = a => a*2;//简洁,类似python lambda 函数
    
    let show = function (a){
      return a*2;
    }
    

    函数-参数

    • 参数扩展/展开 ...args
      • 收集剩余的参数,必须是最后一个参数位置
      • 展开数组,展开后效果和直接把数组的内容写在这儿一样
    • 默认参数
    //收集参数
    function show(a,b,...args){
      console.log(a);//12
      console.log(b);//3
      console.log(...args);//[45,55,78,23]
    }
    show(12,3,45,55,78,23);
    
    //展开数组
    let arr = [1,2,3];
    //...arr
    //1,2,3
    
    function show(a,b,c){
      alert(a);
      alert(b);
      alert(c);
    }
    
    //show(1,2,3);//正常调用数组
    //show(...arr);//es6展开数组,效果相同
    
    let arr1 = [1,2,3];
    let arr2 = [5,6,7];
    
    let arr = [...arr1,...arr2];
    console.log(arr);//[1,2,3,5,6,7]
    
    function show(...args){
      fn(...args);
    }
    function fn(a,b){
      alert(a+b);
    }
    show(12,5);
    
    //默认参数
    function show(a,b=5,c=12){
      console.log(a,b,c);
    }
    show(88);//88,5,12
    show(88, 12);//88,12,12
    show(88,12,4);//88,12,4
    

    解构赋值

    • 左右两个边结构必须一样
    • 右边必须是个东西
    • 声明和赋值赋值不能分开,必须在一句话里完成
    let [a, b, c] = [1, 2, 3]
    console.log(a, b, c);//1,2,3
    
    let {x, y, z} = {x: 1, y: 2, z: 3}
    console.log(x, y, z);//1,2,3
    
    let [json, arr, num, str] = [{ a: 1, b: 2 }, [1, 2, 3], 8, 'str']
    console.log(json, arr, num, str);
    
    //右边必须是个东西
    let [a,b] = {2,3};//报错!
    
    //声明和赋值赋值不能分开
    let [a,b];
    [a,b] = [1,2];//报错!
    

    数组

    • 新增4个方法,mapreducefilterforEach
    • map : 映射,一个对一个
    let arr = [12, 5, 8];
    let result = arr.map(function (item) {
        return item*2
    })
    // 简写
    let result2 = arr.map(item=>item*2);
    console.log(result);//[ 24, 10, 16 ]
    console.log(result2);//[ 24, 10, 16 ]
    
    let score = [18, 86, 88, 24];
    let result3 = score.map(item => item >= 60 ? '及格' : '不及格')
    console.log(result3);//[ '不及格', '及格', '及格', '不及格' ]
    
    • reduce : 汇总,一堆出来一个
      • 用于比如,算个总数,算个平均
    //总和
    var arr = [1, 3, 5, 7]
    var result = arr.reduce(function (tmp, item, index) {
        //tmp 上次结果,item当前数,index次数1开始
        console.log(tmp, item, index);
        return tmp + item;
    })
    console.log(result)
    
    //求平均数
    var arr = [1, 3, 5, 7]
    var result = arr.reduce(function (tmp, item, index) {
        if (index != arr.length - 1) { 
            // 不是最后一次
            return tmp + item
        } else {
            //最后一次
            return (tmp + item)/arr.length
        }
    })
    console.log(result);
    
    • filter : 过滤器 ,保留为true的
    //返回被3整除的数
    var arr = [12, 4, 8, 9]
    var result = arr.filter(item => (item % 3 === 0) ? true : false)
    //简化
    var result = arr.filter(item => item % 3 === 0)
    
    //价格筛选
    var arr = [
        { title: '苹果', price: 10 },
        { title: '西瓜', price: 20 },
    ]
    var result = arr.filter(item=> item.price >= 20)
    
    • forEach : 循环迭代
    var arr = [12, 4, 8, 9]
    var result = arr.forEach(item => console.log(item))
    var result = arr.forEach((item, index)=>console.log(item, index))
    

    字符串

    • 新增两个方法
      • startsWith :以什么开头
      • endsWith : 以什么结尾
    var url = 'http://qq.com'
    console.log(url.startsWith('http'));//true
    console.log(url.endsWith('com'));//true
    
    • 字符串模版
      • 使用反引号, ${变量} 直接把东西塞到字符串中
      • 可以折行
    let a = 12
    let str1 = `asdf${a}`
    console.log(str1)
    
    let title = '标题'
    let content = '内容'
    let str = `<div>
    <h1>${title}</h1>
    <p>${content}</p>
    `
    console.log(str)
    <div>
    <h1>标题</h1>
    <p>内容</p>
    

    面向对象-基础

    • 原来写法
      • 类和构造函数一样
      • 属性和方法分开写的
    //老版写法
    function User(name,pass){
      this.name = name;
      this.pass = pass;
    }
    
    User.prototype.showName = function(){
      alert(this.name);
    }
    
    User.prototype.showPass = function(){
      alert(this.pass);
    }
    
    var u1 = new User('bule','121212');
    u1.showName();
    u1.showPass();
    
    //老版继承
    function VipUser(name, pass, level) {
        User.call(this, name, pass)
        this.level = level
    }
    VipUser.prototype = new User()
    VipUser.prototype.constructor = VipUser
    VipUser.prototype.showLevel = function () {
        console.log(this.level)
    }
    
    var v1 = new VipUser('blue', '1234', 3)
    v1.showName()
    v1.showLevel()
    
    • 新版面向对象
      • 有了 class 关键字、构造器和类分开了
      • class 里面直接加方法
      • 继承,super 超类==父类
    class User {
      constructor(name,pass){
        this.name = name;
        this.pass = pass;
      }
      showName(){
        console.log(this.name);
      }
      showPass(){
        console.log(this.pass);
      }
    }
    
    //新版继承
    class VipUser extends User{
      constructor(name,pass,level){
        super(name,pass);
        this.level = level;
      }
      
      showLevel(){
        alert(this.level);
      }
    }
    
    var v1 = new VipUser('blue', '1234', 3)
    v1.showName()
    v1.showLevel()
    

    面向对象应用

    • React
      • 用于构建用户界面的 JavaScript 库
      • 组件化,一个组件就是一个 class
      • 强依赖于JSX == bable == browser.js

    json

    • JSON 格式
      • JavaScript Object Notation 的缩写,是一种用于数据交换的文本格式
      • JSON 是 JS对象 的严格子集
      • JSON 的标准写法
      • 只能用双引号
      • 所有的key都必须用双引号包起来
    • JSON 对象
      • JSON 对象是 JavaScript 的原生对象,用来处理 JSON 格式数据,有两个静态方法
      • JSON.parse(string) :接受一个 JSON 字符串并将其转换成一个 JavaScript 对象。
      • JSON.stringify(obj) :接受一个 JavaScript 对象并将其转换为一个 JSON 字符串。
    //json的标准写法
    let a = '{"a" : 12,"b" : "lalala"}';
    
    let json = {"a":12,"b":5};
    let str = 'hi,' + JSON.Stringify(json);//hi,{"a":12,"b":5}
    var url = 'http://www.xx.com/' + encodeURIComponent(JSON.stringify(json));//http://www.xx.com/%7B%22a%22%3A12%2C%22b%22%3A5%7D
    
    var str = '{"a": 12, "b": 4, "c": "abc"}'
    var json = JSON.parse(str)
    console.log(json);//{ a: 12, b: 4, c: 'abc' }
    
    • json的简写
      • 名字和值一样时,保留一个就可以
      • json中包含的函数可以省略 :function
    //老版
    let json = {a:a,b:b};
    //新版
    let json = {a,b,c:123};
    
    //老版
    let json = {
      a:12,
      show:function(){
        alert(this.a);
      }
    }
    
    //新版
    let json = {
      a:12,
      show(){
        alert(this.a);
      }
    }
    
    • 对象(object)
      • 是 JavaScript 语言的核心概念,也是最重要的数据类型
        对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合
      • 对象的所有键名都是字符串, 所以加不加引号都可以
        如果键名是数值,会被自动转为字符串
      • 对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型
      • 如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用
      • in 运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值
      • for...in循环用来遍历一个对象的全部属性

    Promise

    • 异步和同步

      • 异步,操作之间没啥关系,可同时执行多个操作, 代码复杂
      • 同步,同时只能做一件事,代码简单
    • Promise 对象

      • 用同步的方式来书写异步代码
        Promise 让异步操作写起来,像在写同步操作的流程,不必一层层地嵌套回调函数
      • 改善了可读性,对于多层嵌套的回调函数很方便
      • 充当异步操作与回调函数之间的中介,使得异步操作具备同步操作的接口
    • Promise 也是一个构造函数

      • 接受一个回调函数f1作为参数,f1里面是异步操作的代码
      • 返回的p1就是一个 Promise 实例
      • 所有异步任务都返回一个 Promise 实例
      • Promise 实例有一个then方法,用来指定下一步的回调函数
    //原理
    function f1(resolve, reject) {
      // 异步代码...
    }
    var p1 = new Promise(f1);
    p1.then(f2); // f1的异步操作执行完成,就会执行f2。
    
    • Promise 使得异步流程可以写成同步流程
    // 传统写法
    step1(function (value1) {
      step2(value1, function(value2) {
        step3(value2, function(value3) {
          step4(value3, function(value4) {
            // ...
          });
        });
      });
    });
    
    // Promise 的写法
    (new Promise(step1))
      .then(step2)
      .then(step3)
      .then(step4);
    
    let p = new Promise(function (resolve,reject){
        //异步代码
        //resolve - 成功
        //reject - 失败
        $.ajax({
          url:'',
          dataType:'json',
          success(arr){
            resolve(arr);
          },
          error(err){
            reject(err);
          }
        })
    })
    
    //当Promise执行有结果了,就执行此函数
    p.then(function(arr){
      //成功操作...
    },function(err){
      //失败操作...
    })
    
    • Promise.all(promiseArray)方法
      • 将多个Promise对象实例包装,生成并返回一个新的Promise实例
      • promise数组中所有的promise实例都变为resolve的时候,该方法才会返回
      • 并将所有结果传递results数组中
      • promise数组中任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的promise对象
    //用到点上
    let p1 = new Promise(function (resolve,reject){
        //异步代码
        //resolve - 成功
        //reject - 失败
        $.ajax({
          url:'',
          dataType:'json',
          success(arr){
            resolve(arr);
          },
          error(err){
            reject(err);
          }
        })
    })
    
    let p2 = new Promise(function (resolve,reject){
        //异步代码
        //resolve - 成功
        //reject - 失败
        $.ajax({
          url:'',
          dataType:'json',
          success(arr){
            resolve(arr);
          },
          error(err){
            reject(err);
          }
        })
    })
    
    Promise.all([
      p1,p2
    ]).then(function(arr){
      //arr为两次ajax的结果组成的数据
      //全部成功操作...
    },function(err){
      //至少有一个失败后操作...
    })
    
    //简化
    function createPromise(url){
      return new Promise (function(resolve,reject){
        $.ajax({
          url,
          dataType:'json',
          success(arr){
            resolve(arr);
          },
          error(err){
            reject(err);
          }
        })
      })
    }
    
    Promise.all([
      createPromise('url1'),
      createPromise('url2')
    ]).then(function(arr){
      //arr为两次ajax的结果组成的数据
      //全部成功操作...
    },function(err){
      //至少有一个失败后操作...
    })
    
    //高版本jq自带支持Promise,不需要我们自己封装函数,精简成
    Promise.all([
      $.ajax({url:'url1',dataType:'json'}),
      $.ajax({url:'url2',dataType:'json'})
    ]).then(function(res){
      //arr为两次ajax的结果组成的数据
      //全部成功操作...
       let [arr,json] = res;
    },function(err){
      //至少有一个失败后操作...
    })
    
    • Promise.rece([p1, p2, p3])
      • Promse.race就是赛跑的意思
      • 哪个结果获得的快,就返回那个结果
      • 不管结果本身是成功状态还是失败状态
      Promise.rece([
      $.ajax({url:'url1',dataType:'json'}),
      $.ajax({url:'url2',dataType:'json'})
    ])
    

    generator-认识生成器函数

    • generator 生成器函数
      • 普通函数,一路到底
      • generator函数,中间可以停,到哪停呢,用 yield 配合,交出执行权
      • yield 有 放弃、退让、退位的意思
      • 需要调用next()方法启动执行,需要遇到 yield 停, 踹一脚走一步
      • generator函数前面加一个 * 两边可以有空格,或靠近函数或function
      • 不能缩写function成箭头函数
      • 背后实际生成多个小函数,实现走走停停
    //普通函数
    function show(){
      alert('a');
      alert('b');
    }
    
    //generator函数
    function * show(){
      alert('a');
      yield,
      alert('b');
    }
    let genObj = show();
    genObj.next();//弹出a,遇到yield停止运行
    genObj.next();//弹出b
    genObj.next();// 最后了,没有结果
    

    generator-yield是啥

    • yield
      • 既可传参,又可以返回
      • 第一个next()传参无效,只用来启动
    • 如果函数前漏掉 *
      • 就是普通函数
      • 如果有yield会报错, ReferenceError: yield is not defined
      • yield 只能在Generator函数内部使用
    //yield 传参
    function * show(){
      alert('a');
       let a = yield;
      alert('b');
      alert('a');
    }
    var gen = show()
    gen.next() //弹出a
    gen.next() //弹出b 和 undefined 因为没有传参,yield没有返回值
    
    let gen = show();
    gen.next(12);//弹出a 第一次执行到yield,但没有执行赋值
    gen.next(4);//弹出b,弹出5
    
    //yield 返回
    function * show(){
      alert("a");
      yield 12;
      alert('b');
      return 55;
    }
    let gen = show();
    let res1 = gen.next();
    console.log(res1);//{value:12,done:false}
    let res2 = gen.next();
    //无return时
    console.log(res2);//{value:undefined,done:true}
    
    //有return时
    console.log(res2);//{55,done:true}
    

    generator-实例

    • 异步操作处理
      • 回调
      • Promise 适合一次读一组
      • generator 适合逻辑性的
    //npm i runner
    runner(function * (){
      let data1 = yield $.ajax({url:'url1',dataType:'json'});
    let data2 = yield $.ajax({url:'url2',dataType:'json'});
    let data3 = yield $.ajax({url:'url3',dataType:'json'});
    })
    
    console.log(data1,data2,data3);
    
    //带逻辑-普通回调
    $.ajax({url:'url1',dataType:'json'},success(userData){
      if(userData == 'vip'){
    $.ajax({url:'url1',dataType:'json'},success(item){
         //系列操作...
      },error(err){
        console.log(err);               
      })
      }
    })
    
    //带逻辑-Promise  (比普通的回调更麻烦)
    Promise.all([ $.ajax({url:'url1',dataType:'json'})
    ]).then(res => {
      let userData = res[0];
      if(userData == 'vip'){
        Promise.all([
            $.ajax({url:'url1',dataType:'json'})
        ]).then(res => {
          
         },err => {
          console.log(err);
        })
      }
    },err => {
      console.log(err);
    })
    
    // 带逻辑-generator
    runner(function * () {
        let userData = yield $.ajax({url: 'getUserData'})
    
        if (userData.type == 'VIP') {
            let items = yield $.ajax({url: 'getVIPItems'})
        } else {
            let items = yield $.ajax({url: 'getItems'})
        }
    })
    
    // yield 实例,用同步方式写异步
    server.use(function * () {
        let data = yield db.query(`select * from user_table`)
        this.body = data
    })
    

    ES7 预览

    • 数组
      • arr.includes() 数组是否包含某个东西

      • 数组的 arr.keys(), arr.values(),arr.entries()

      • for ... in 遍历数组 下标 key 能用于json

      • for ... of 遍历数组 值 value, 不能用于json

      • keys 所有的key拿出来

      • values 所有的values拿出来

      • entries 所有的key-value对拿出来

    let arr = ['a', 'b', 'c']
    console.log(arr.includes(1))//false
    
    for (let i in arr) {
        console.log(i) // 循环的时下标 key
    }
    
    for (let i of arr) {
        console.log(i) // 循环的是值 value
    }
    
    for (let i of arr.keys()) {
        console.log('>'+i)
    }
    
    for (let i of arr.values()) {
        console.log('>'+i)
    }
    
    for (let [key, value] of arr.entries()) {
        console.log('>' + key + value)
    }
    
    let json = { a: 12, b: 5, c: 7 }
    for (let i in json) {
        console.log(i)
    }
    
    • 幂 **
      3**8:3的8次方

    • 字符串

      • padStart()/padEnd() 指定宽度,不够就补空格或指定字符
    console.log('=' + 'abcd'.padStart(6, '0') + '=')//=00abcd=
    console.log('=' + 'abcd'.padEnd(6, '0') + '=')//=abcd00=
    
    • 容忍度

      • [1, 2, 3,] 老版数组最后不能有逗号,新的可以有
      • 函数参数最后多的逗号也可以
    • async await

      • 和 generator yield 类似
      • generator 不可以写成箭头函数, async 可以
      • 不依赖外部runner,标准统一,性能提高
    async function show() {
        console.log(1)
        await
        console.log(2)
    }
    
    async function readData(){
      let data1 = await $.ajax({url:'url1',dataType:'json'});
    let data2 = await $.ajax({url:'url1',dataType:'json'});
    let data3 = await $.ajax({url:'url1',dataType:'json'});
    
    console.log(data1,data2,data3);
    }
    
    //简写
    async () => {
      let data1 = await $.ajax({url:'url1',dataType:'json'});
    let data2 = await $.ajax({url:'url1',dataType:'json'});
    let data3 = await $.ajax({url:'url1',dataType:'json'});
    
    console.log(data1,data2,data3);
    }
    

    相关文章

      网友评论

          本文标题:深入解读ES6

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