Web全栈笔记之ES6

一、简介

ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
标准的制定者有计划,以后每年发布一次标准,使用年份作为版本。因为ES6的第一个版本是在2015年发布的,所以又称ECMAScript 2015(简称ES2015)。
2016年6月,小幅修订的《ECMAScript 2016 标准》(简称 ES2016)如期发布。由于变动非常小(只新增了数组实例的includes方法和指数运算符),因此 ES2016 与 ES2015 基本上是同一个标准,都被看作是 ES6。根据计划,2017年6月将发布 ES2017。

二、概述

除了正常运行模式,ECMAscript 5添加了第二种运行模式:”严格模式”(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。
设立”严格模式”的目的,主要有以下几个:
  •    消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;
  •    消除代码运行的一些不安全之处,保证代码运行的安全;
  •    提高编译器效率,增加运行速度;
  •    为未来新版本的Javascript做好铺垫。
“严格模式”体现了Javascript更合理、更安全、更严谨的发展方向,包括IE 10在内的主流浏览器,都已经支持它,许多大项目已经开始全面拥抱它。
另一方面,同样的代码,在”严格模式”中,可能会有不一样的运行结果;一些在”正常模式”下可以运行的语句,在”严格模式”下将不能运行。掌握这些内容,有助于更细致深入地理解Javascript,让你变成一个更好的程序员。

三、演示

"use strict"放在脚本文件的第一行,则整个脚本都将以"严格模式"运行。如果这行语句不在第一行,
则无效,整个脚本以"正常模式"运行。如果不同模式的代码文件合并成一个文件,这一点需要特别注意。
1.创设eval作用域
    "use strict"//严谨模式
    var i = 1;
    var str=" var i = 5;";
    eval(str);
    console.log();//在严谨模式下 只会输出第一定义i的变量,不会被str所影响
2.禁止this关键字指向全局对象
function f(){
    "use strict";
    console.log(this);//这个指向obj
    function time(){
        this.name="obj";
        console.log(this);//window在严格模式下就是undefined 报错
    }
    time();
    }
    var obj ={};
    obj.f = f;
    obj.f();
3.全局变量显式声明
    "use strict"
    var num = 2;//严格模式下 定义变量必须加var 不加var 不给你用
    function show(){
        "use strict"
         var num = 1;//严格模式下 禁止 函数内的变量变成全局
        console.log(num)
    }
    show();
    console.log(num)
4.ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
{
    let a = 10;//a只属于这个块({})里面外面不可以用
    var b = 1;
}
    console.log(a)//undefined 报错
    console.log(b)//1

for循环的计数器,就很合适使用let命令。

    // for循环的计数器,就很合适使用let命令。
     var arr = [];
     for (var  i = 0; i < 10; i++) {
         arr[i] = function () {
             console.log(i)
         };
     }
     arr[2]();
    //let 块作用域 for循环相当于 独立的一块
    arr[1] = function () {
     console.log(i)
     };
    arr[2] = function () {
        console.log(i)
     };
    arr[3] = function () {
        console.log(i)
    };
    arr[4] = function () {
        console.log(i)
    };
5.不存在变量提升
    console.log(foo);
console.log(bar);
var foo = 2;//提升变量后 输出的时候没有赋值 所以 是undefined
let bar = 2;//let 不存在变量提升
6.暂时性死区
    var tmp = 123;
if (true) {
    //tmp = 'abc';//报错 死区
    let tmp;// let 必须在对顶部
    tmp = 'abc';
    console.log(tmp);//输出abc
}
    console.log(tmp);//输出123
7.不允许重复声明 let不允许在相同作用域内,重复声明同一个变量
(function () {
       let a = 10;//let 不能重复定义 只能有一个
       var a = 1;//定义报错
         console.log(a);
     })()
8.ES6的块级作用域
    // let实际上为JavaScript新增了块级作用域。
     function f1() {
       let n = 5;
       if (true) {
         let n = 10;//let限定在if这一块里面 其他无妨无效
       }
       console.log(n);
     }
     f1()//输出5
9.const命令
    //const声明一个只读的常量。一旦声明,常量的值就不能改变。
    const PI = [];//设置常量 无法修改
    //PI = 3;//修改报错
    PI[0]=123;
    console.log(PI)
10.数组的解构赋值
// ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构
     let [a, b, c] = [1, 2, 3];//数组方法 定义变量
     console.log(a) // 1
     console.log(b) // 2
     console.log(c) // 3

     let [var1, ...var2] = [1, 2, 3, 4];//...var2代表多个
     console.log(var1);
     console.log(var2);
-------------------------------------------------------------------
     let [x = 1, y = x] = [];
    console.log(x,y)//输出1 1
     let [x = 1, y = x] = [2];
    console.log(x,y)//输出2 2 定义了x=2
     let [x = 1, y = x] = [1, 2];
    console.log(x,y)//输出1 2
     let [x = y, y = 1] = [];//报错
     console.log(x,y)//因为x = y 的时候y还没有赋值
11.对象的解构赋值
    // 解构不仅可以用于数组,还可以用于对象
    var { bar,foo  } = { foo: "aaa", bar: "bbb" };
    foo // "aaa"
    bar // "bbb"
    console.log(foo,bar);
    var obj={
        name:"abc",
        arr:[1,2,3,4],
        json:{
            name:"json",
        }
    }
    var {name,arr,json} = obj;
    console.log(name,arr,json);
    var [a,b,c,d] = obj.arr//a,b,c,d 相当于obj里面数组的1,2,3,4
    console.log(a,b,c,d)
12.函数参数的默认值
// 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。
    function show (a,b){
        var b=b||0;
        console.log(a+b);
    }
    show(5,6);
// ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。
    function show (a=2,b=1){
        console.log(a+b);
    }
    show(5);
13.与解构赋值默认值结合使用
    // 参数默认值可以与解构赋值的默认值,结合起来使用。
    function  show([a,b,c]){//相当于把数组里面的值传进去
        console.log(a+b+c);
    }
    var arr = [1,2,3]
    show(arr);
    var arr=[5,6,21,8,7,1,5];//...arr等于arr数组里面的5,6,21,8,7,1,5 抽出来
    console.log(Math.max(...arr));
14.作用域
一个需要注意的地方是,如果参数默认值是一个变量,则该变量所处的作用域,
与其他变量的作用域规则是一样的,即先是当前函数的作用域,然后才是全局作用域。
     var x = 1;
     function f(x, y = x) {
        console.log(y);
     }
     f(2)//传2 x=2
-----------------------------------
     let x = 1;
        //x等于1 y=x
     function f(y = x) {
       let x = 2;
         //y=1
       console.log(y);
     }
     f();
15.rest参数
ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数,这样就不需要使用arguments对象了。
rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
    var arr=[5,6,21,8,7,1,5];//...arr等于arr数组里面的5,6,21,8,7,1,5 抽出来
    console.log(Math.max(...arr));
    // 替代数组的apply方法
    // 由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。
    console.log(Math.max(...arr))
    // ES5的合并数组
    var  arr =[1,2,3];
    var arr2=[4,5,6];
    var arr3=[7,8,9];
    var all=arr.concat(arr2,arr3);
    console.log(all);
    // ES6的合并数组
    var all = [...arr,...arr2,...arr3];
    console.log(all);
16.箭头函数
// ES6允许使用“箭头”(=>)定义函数。=>等于return
    var a = 5;
    fn = a => a;
    console.log(fn(a))
    //正常函数写法
    function fn(a){
        return a;
    }
    console.log(fn(a))
--------------------------------------------------
    fn = (a,b) => {
        let c = a+b;
        return c;
    };
    console.log(fn(3,6))
    //正常函数写法
    function fn(a,b){
        var c = a+b;
        return c;
    }
    console.log(fn(3,6))
/*  使用注意点
    箭头函数有几个使用注意点。
    (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
    (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
    (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。
*/  

    function Person(){
        //输出传进来的数据 arguments 传进来的全部参数
        console.log(arguments)
        var sum = 0;
        for(var value of arguments){
            sum += value;
        }
        console.log(sum)
    }
    Person(2,3,5,4,5,6)
//箭头函数不可使用arguments
    Person = (...arr) => {
        var sum = 0;
        for(var value of arr){
            sum += value;
        }
        console.log(sum)
    }
    //指向window
    Person(2,3,5,4,5,6)
    var obj = {
            name:"obj",
            show:()=>{
                setTimeout(()=>{
                    console.log(this)//指向window
                })
            }
        }
        obj.show()
    //=>函数体内的this对象 不能指向本身
    var obj = {
            name:"obj",
            show:()=>{
                setTimeout(()=>{
                    console.log(this)//指向window
                })
            }
        }
        obj.show()
    //function指向本身
        var obj = {
            name:"obj",
            show:function(){
                setTimeout(()=>{
                    console.log(this)//指向当前的this
                })
            }
        }
        obj.show()
17.字符串转换
    var a ="hello";
    var b ="冒泡";
    //ES5字符串拼接
    var str = a+""+b;
    //ES6字符串拼接
    var str=`${a}${b}`;
    var  str =`<a href="">${b}a>`;
    console.log(str);
18.对象calss
   //ES5构造函数
    //定义类
    function Person(name){
        this.name=name;
    }
    //创建原型
    Person.prototype.show =function(){
        console.log(this.name);
    }
    var  obj =new Person("abc");
    obj.show();//调用obj原型 show
    //继承
    function Son(name,age){
            this.age = age
    //      Person.apply(this,arguments)
            Person.call(this,name)
        }
    Son.prototype = new Person();
    var s = new Son("son",18);
    s.show()
    console.log(s.age)
    //ES6构造函数
    //1.Class基本语法
        class Person{
        //构造方法
        constructor(name){
            this.name = name;
        }
        //原型方法
        show(){
            console.log(this.name);
        }
    }
    var  obj = new  Person("es6");
    obj.show()
    // 2.Class的继承----------------------------
    // Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。
    class Son extends Person{
        constructor(name,age){
            super(name);
            this.age = age;
    //      this.name = "abc";
        }
        show(){
            console.log(this.name,this.age)
        }
    }
    var s = new Son("kkk",18);
    s.show();

Babel

Babel 是一个广泛使用的转码器,可以将ES6代码转为ES5代码,从而在现有环境执行。
这意味着,你可以现在就用ES6编写程序,而不用担心现有环境是否支持。下面是一个例子。
    进行Babel转码。这意味着,如果项目要运行,全局环境必须有Babel,也就是说项目产生了对环境的依赖。
另一方面,这样做也无法支持不同项目使用不同版本的Babel。

    一个解决办法是将 babel-cli 安装在项目之中。
    $ sudo cnpm install babel-cli -g//先安装全局
    $ sudo cnpm install babel-preset-es2015//再安装es2015标准
    基本用法如下。
    # 转码结果输出到标准输出
    $ babel text.js//接着输出标准

    # 转码结果写入一个文件
    # --out-file 或 -o 参数指定输出文件
    $ babel example.js --out-file compiled.js
    # 或者
    $ babel example.js -o compiled.js //转换文件

    # 整个目录转码
    # --out-dir 或 -d 参数指定输出目录
    $ babel src --out-dir lib
    # 或者
    $ babel src -d lib

    配置文件 .babelrc

    Babel的配置文件是 .babelrc ,存放在项目的根目录下。使用Babel的第一步,就是配置这个文件。
    该文件用来设置转码规则和插件,基本格式如下
    {
      "presets": ["es2015"],
      "plugins": []
    }



    ES6新特性在Babel下的兼容性列表

    ES6特性   兼容性
    箭头函数    支持
    类的声明和继承 部分支持,IE8不支持
    增强的对象字面量    支持
    字符串模板   支持
    解构  支持,但注意使用方式
    参数默认值,不定参数,拓展参数 支持
    let与const   支持
    for of  IE不支持
    iterator, generator 不支持
    模块 module、Proxies、Symbol    不支持
    Map,Set 和 WeakMap,WeakSet   不支持
    Promises、Math,Number,String,Object 的新API    不支持
    export & import 支持
    生成器函数   不支持
    数组拷贝    支持

你可能感兴趣的:(Web前端开发)