ES6关键字

什么是ES6?ECMAScript 6(简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了。其中相比较于ES5新增了诸多的特性,并且ES6可转换为ES5的语法。

一、let关键字

  • let和var的区别在于申明变量的作用域,var声明的作用域是全局的,let申明的变量作用域是块级作用域。最主要的体现就在于循环之中,我们需要通过循环基数(即index)来做些什么的时候,再使用var申明的时候我们的常常使用自运行函数来解决这一问题,但是使用let之后,js会自动的帮我们确定当前循环的变量基数的运行区间,不再会受到全局的影响。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    function n() {
    let a = 1;
    if (true) {
    let a = 5;
    }
    console.log(a); // 输出1
    };

    2.没有块级作用域引起的问题: if的块级
    var func;
    if (true) {
    var name = 'why';
    func = function () {
    console.log(name);
    }
    func()
    }
    name = 'kobe'
    func()
    console.log(name);

    var name = 'why'
    function abc(bbb) { // bbb = 'why'
    console.log(bbb);
    }
    abc(name)
    name = 'kobe'

    // 3.没有块级作用域引起的问题: for的块级
    // 为什么闭包可以解决问题: 函数是一个作用域.
    // var btns = document.getElementsByTagName('button');
    // for (var i=0; i<btns.length; i++) {
    // (function (num) { // 0
    // btns[i].addEventListener('click', function () {
    // console.log('第' + num + '个按钮被点击');
    // })
    // })(i)
    // }

    const btns = document.getElementsByTagName('button')
    for (let i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', function () {
    console.log('第' + i + '个按钮被点击');
    })
    }
  • let不再存在变量提升的现象,必须声明之后在使用。 这一效果的实现方式是展示性死区,再JS解析到当前代码段之中有通过let申明的变量,则再这一变量声明的代码真正执行之前的区域就是对应的死区,死区之中对于当前变量的使用都将会报错。如果再当前区域外通过var声明了全局变量,但是此区域之中有let声明的名称相同的变量则,这一变量再这一区域之中会被封锁,全局同名变量将会没有作用。

  • 同一区域之中不可以声明相同名称的变量。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    {
    var a=1;
    var a=2;//无报错
    }
    {
    let a=1;
    let a=2;//Uncaught SyntaxError: Identifier 'a' has already been declared
    }

    二、const

    • 声明常量内容此类变量一旦声明则不可以进行修改
    1
    2
    const PI = 3.1415;
    PI = 3;//Uncaught TypeError: Assignment to constant variable.
    • const通过保证变量指向的内存区域的对应的数值的不变来达到这一效果的
    1
    2
    3
    const PI={}  
    PI.num=3.14159;//不会报错
    PI={num=3.14159};//VM1187:1 Uncaught SyntaxError: Identifier 'PI' has already been declared
    • const声明的常量必须声明时就赋值
    1
    const PI; // SyntaxError: Missing initializer in const declaration
    • const声明的常量跟let的作用域一样
    1
    2
    3
    4
    if (true) {
    const PI = 3.14159;
    }
    console.log(PI); // Uncaught ReferenceError: PI is not defined

    三、super

    this关键字总是指向函数所在的当前对象,ES6又新增super关键字,指向当前对象的原型对象。两种使用方式:

    1、当做函数使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class parent {
    constructor() {
    console.log(11)
    }
    }
    class child extends parent{
    constructor() {
    super();
    }
    }
    let c = new child();//打印11

    当做函数使用时,super()调用会生成一个空对象,作为context来调用父类的constructor,返回this对象,作为子类constructor的context继续调用构造函数。

    2、当做对象使用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const proto = {
    foo: 'hello'
    };
    const obj = {
    foo: 'world',
    find() {
    return super.foo;
    }
    };
    Object.setPrototypeOf(obj, proto);
    obj.find() // "hello"

    上面代码中,对象obj.find()方法之中,通过super.foo引用了原型对象proto的foo属性。

    3、注意区分super与this

    super与this的区别,this关键字最终指向的是调用它的对象。下面两个例子

    1
    2
    3
    4
    function GetThis(){
    console.log(this);
    };
    GetThis();//打印出window对象。

    其实最后的调用我们也可以写成window.GetThis();调用他的就是window对象。

    1
    2
    3
    4
    5
    6
    7
    var getThis={ 
    user:'me',
    fn:function(){
    console.log(this);
    }
    }
    getThis.fn();//打印的就时getThis对象;

    this与super结合的例子

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    const proto = {
    x: 'hello',
    foo() {
    console.log(this.x);
    },
    };
    const obj = {
    x: 'world',
    foo() {
    super.foo();
    }
    }
    Object.setPrototypeOf(obj, proto);
    obj.foo()// "world"

    上面代码中,super.foo指向原型对象proto的foo方法,但是绑定的this却还是当前对象obj,因此输出的就是world。