ES6经典入门到进阶

小菜鸟战斗机 2018-3-26 210

ECMA的历史:

  1. 早期的 ECMA版本是 ECMA-262 标准,可以俗称 1.0
  2. 后续好几年,不断提案不断改进,后来一直到2011年,版本其实到了 ECMA5.x了
  3. 后来为了统一版本,标准委员会最终决定,标准在每年的 6 月份正式发布一次,作为当年的正式版本
  4. 在2015年6月,ES6正式发布,后续的小版本可能是 6.1,6.2.... 也可以用年来标记
  5. 所以ES2015才是正规的 ES6的名称
  6. 而,2016年6月,也发布一个版本(这个版本新增了一个数组的 includes和幂运算符),其实是ES6.1,或者叫ES2016,有人也俗称ES7,其实这个称呼,不太对
  7. 2017年6月,发布了几个改动(async await), 名字应该叫 ES2017,有人说ES8,我的天。
  8. 2018年6月, 还是会发布几个改动,其实都应该叫ES6,或者以年份命名。
  9. 聪明的开发者,现在都不叫ES7 8了, 叫 ESnext, 特指,"下一代 JavaScript 语言"

总结:
2015年6月 ES6正式推出, 叫 ES2015
2016年6月 ES6.1推出, 叫ES2016
2017年6月 ES6.2推出, 叫ES2017

或者叫: ESnext

  1. 现在是开源的世界:
    任何人都可以向标准委员会(又称 TC39 委员会)提案,要求修改语言标准
    一种新的语法从提案到变成正式标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准。
    Stage 0 - Strawman(展示阶段)
    Stage 1 - Proposal(征求意见阶段)
    Stage 2 - Draft(草案阶段)
    Stage 3 - Candidate(候选人阶段)
    Stage 4 - Finished(定案阶段)
    一个提案只要能进入 Stage 2,就差不多肯定会包括在以后的正式标准里面。ECMAScript 当前的所有提案,可以在 TC39 的官方网站Github.com/tc39/ecma262查看。

ES6环境搭建 (目前ES6的大部分属性已经被浏览器支持,所以可以不用babel)

现在不像以前了,IE可以忽略,像chrome等都是标准委员之一,定制好,基本浏览器下一个版本就逐渐支持,所以速度还是挺快的

webpack3.0  编译
babelrc    配置
Google 公司的Traceur转码器

cnpm install babel-cli -g
    需要依赖包:  babel-preset-es2015    babel-cli
安装 live-server  或者webpack3.0配置

let、 const、块级代码作用域

let、const 有块级代码作用域
之前var只有在函数里面才有作用域一说
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景。

  1. 块级作用域可以任意嵌套
    {{{let a = 10}}}
  2. // IIFE 写法
1
(function () {
2
  var tmp = ...;
3
  ...
4
}());
1
// 块级作用域写法
2
{
3
  let tmp = ...;
4
  ...
5
}

let注意的地方:

    1. 没有预解析,不存在变量提升
        但是有 TDZ,暂时性死区
        ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
                let a=1;
                if(true){
                    //TDZ开始 (temporal dead zone,简称 TDZ) 暂时性死区
                    console.log(a);
                    let a=12;  //TDZ 结束
                }
        总结: 在代码块内,只要在let定义变量之前使用,都是有问题的
    2. 不能重复定义
    3. 特殊的for循环,for循环里面是父级作用域,里面又一个作用域
                for(let i=0; i<3; i++){
                    let i='abc';
                    console.log(i);
                }
例子: 关于循环的 i, 选项卡索引
    var a = [];
    for (var i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 10
-----------------------------------
const和let差不多,只不过人家是常量,不能改变:
        const a =['a','b'];
        a.push('c');
        console.log(a);
        ----------------------  
        const a = Object.freeze(['a','b']);
        a.push('c');
        console.log(a);
  1. 解构赋值
    非常有用,特别是数据交互的时候,后台传过来一堆数据,你需要挑选你想要的就好
    注意: 两边结构需要一直
    a). 数据解构赋值:
    let [a='abc']=[] 解构默认值(里面填写undefined和null的区别)
    let [a, b='banana'] = ['aaa', undefined]; 和 let [a, b='banana'] = ['aaa', null];
    b). 对象解构赋值:
    let {a,b} = {a:'apple', b:'banana'};
    一个小坑:
        let a;
        {a} = {a:'apple'}   需要写成这种   ({a} = {a:'apple'} )
    
    例子: 函数传参解构
        let json={a:'111', b:'222'}
        function fn({a, b='Strive'}){
            console.log(a,b);
        }
        fn(json);
        ------------------------------
        封装运动函数: 参数默认值
        function doMove({x=0, y=0}={}){
                    console.log(x, y);
                }
    
                doMove({x:0, y:0});
                doMove({x:10});

    c). 字符串解构赋值:
    const [a,b,c] = 'wel'; 平时工作用的不多

    解构赋值的用途:

    1. 交换两个数的位置
      let x = 5;
      let y = 12;
      let [y,x] = [x, y];
      console.log(x, y);
    2. 函数返回多个值
    3. 提取 JSON 数据
      let jsonData = {
      id: 42,
      status: "OK",
      data: [867, 5309]
      };
      let { id, status, data: number } = jsonData;
      
      console.log(id, status, number);
      // 42, "OK", [867, 5309]
    4. import 模块的时候解构
    5. 封装框架的默认参数
      function ajax(url,{
      type='get',
      fnSucc=function(){},
      fnFail=function(){},
      data={}
      }){
      console.log(
      url,
      type,
      fnSucc,
      fnFail,
      data
      )
      }
          ajax('http://www.baidu.com',{type:'post'});

      ===================================================

  2. 字符串模板
    `` ${}
    好处:
    支持换行

    字符串查找:
    ES5 -> str.indexOf()
    ES6 -> str.includes(xx)

    str.startsWith(xx)      判断字符串开头
    str.endsWith(xx)    判断字符串结尾
    
    str.repeat(3)    字符串的复制
    
    字符串填充:padStart和padEnd
    
    'x'.padStart(指定字符串的最小长度, 补全的字符串);
        'x'.padStart(5, 'ab') // 'ababx'
        'xxx'.padStart(2, 'ab') // 'xxx
  3. 函数的变化 扩展运算符和rest运算符
    1. 函数参数的默认值
      function fn(a='欢迎',b='mmr'){
      console.log(a, b);
      }
      fn('welcome','牧码人');
      fn('welcome','');
      fn('welcome');
    2. 函数参数变量默认是声明的,不能再用let或者const声明
      function foo(x = 5) {
      let x = 1; // error
      const x = 2; // error
      }
    3. 配合对象解构,如果不默认赋值会报错
      function foo({x, y = 5} = {}) {
      console.log(x, y);
      }
      foo() // undefined 5
    4. reset参数, (剩余参数), 必须放到最后
      例子1: function fn(...args){ //求和,不用arguments了,为何,因为有箭头函数

      }
      fn(1,2,3,4,5)
      例子2: 排序
      function fn(...numbers){
      return numbers.sort();
      }
      fn(3,2,-10,90,100);
      箭头函数:
      =>
      注意:

      1. this问题,就是定义时所在的对象,而不是使用时所在的对象
        之前有过开发js的经验,都知道this简直令人丧心病狂
      2. 不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误
      3. 不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

    //函数传入数组
    function fn(a,b,c){
    console.log(a,b,c);
    }
    fn(...[1,2,3])

    例子: 复制数组
    循环
    Array.from()
    [...arr1]

    rest运算符:
    function fn(arg1,...args){}

    for of 循环

    ES2017允许函数参数最后有尾逗号
    function fn(a,b,){
    console.log(a,b);
    }
    fn(1,2,)

参考资料: https://space.bilibili.com/52140273?spm_id_from=333.338.v_upinfo.2#/channel/detail?cid=32135


最新回复 (0)
返回