ES6笔记分享 part 1

ECMAScript ES6 从一脸懵逼到灵活运用

var let const

var let const 的比较

声明与赋值

  • var声明的变量是可以重新赋值的,也可以重复声明

  • letconst声明的变量都是不可以重复声明的

    ​ 即使在不同作用域内可以出现同名变量,但并不相同,只能在各自的作用域中使用

  • 不同的是, let声明的变量是可以重新赋值的,但 const不行

    ​ 注意:用const声明的变量并不是完全不可以改变的

    ​ 如果用const来声明一个对象,虽然无法给这个对象重新赋值,但是我们可以改变对象的属性值(对象是引用类型变量,只改变对象的属性并不会影响指针指向)

    ​ 如果你也不希望改变属性值的话可以使用Object.freeze()方法

变量作用域

  • varfunction scope即函数作用域

    在函数中声明的变量只能在函数中使用,否则就是一个全局变量

    如果在在iffor等语句里定义的变量你只希望在内部使用,var就无法满足,因为它没有在函数里声明,所以会变成一个全局变量,污染全局作用域

  • letconstblock scope即块级作用域

    一对大括号 { } 所包裹的内容即为一个块级作用域,声明的变量只能在块内使用,在块级作用域外调用则会报错

let 和 const 的使用场景

  1. letconst代替IIFE

    IIFE 即 立即执行函数 ,应用之一就用来生成一个私有变量

    // 例如我们在window对象中有一个name属性,如果直接这样声明一个name变量的话会覆盖属性name的值
    // var name = 'Tom';
    
    // 我们通常会用一个立即执行函数来使变量私有化
    (function () {
        var name = 'Tom';
    })();
    
    // 如果使用 let 或者 const 就可以简单实现,只需要用一对大括号包裹起来,就形成了一个块级作用域
    {
        let name = 'Tom';
    }
    
  2. for循环

    for (var i = 0; i < 10; i++) {
        
        console.log(i);	// 输出:0 1 2 3 ... 9
        
        // 我们这里用setTimeout来模拟异步请求
        setTimeout(function() {
            console.log('i:' + i);
            // 这里输出了10个 i:10
            // 因为函数是延迟一秒执行的 此时 for 循环已经结束
        }, 1000)
    }
    
    // 将 var 改成 let 即可得到想要的结果,但不能使用 const !
    
  3. ...

临时性死区 Temporal Dead Zone

变量提升是 JavaScript 将变量的声明移至作用域的顶部

console.log(color);		// 不会报错 而是输出 undefined
var color = 'yellow';

// 因为有了变量提升实际上这段代码是这样的

var color;
console.log(color);		// 所以这里会输出 undefined
color = 'yellow';

/*
  如果将 var 换成 let 则会报 ReferenceError
  在ESMAScript 2015 中, let 也会将变量提块级作用域顶部,但你想在块级作用域中变量的声明之前引用的话就会报ReferenceError, 因为它是在临时性死区中的, const 亦是如此
  我们要养成在变量之前不要使用它的好习惯
  需要注意的是,因为 const 定义的是一个常量,所以声明的同时必须赋初始值,否则会报错
     使用建议( in ES6 ):
     	默认使用 const 
     	当变量需要重新绑定的时候使用 let
     	尽量不使用 var 
*/

Arrow Function 箭头函数

优点:

  1. 简明的语法
  2. 可以隐式返回
  3. 不绑定this

简明的语法

例如我们要用map遍历一个数组使其中的数乘以二返回

const nums = [1, 3, 0, 5];

const double = nums.map(function (num) {
    return num * 2;
});

console.log(double);	// [2, 6, 0, 10]

// 改用箭头函数 
const double2 = nums.map((num) => {
    return num * 2;
});

console.log(double2);	// [2, 6, 0, 10]

箭头函数写法:去掉function关键字, 加上 =>

如果箭头函数只有一个参数的话,()可以省略,没有参数或者有多个参数则必须使用括号并且参数之间用,隔开

隐式返回

显式返回即return关键字加上返回的内容。

箭头函数中的隐式返回:

​ 去掉return关键字 , 去掉 {} , 将表达式写到一行中

用于我们只想简单返回一些内容时,使代码更加简洁

// like this
const double3 = nums.map((num) => num * 2);

注: 因为箭头函数都是匿名函数,匿名函数在递归或者作为回调函数等场景时非常好用,但如果你只想作为一个简单函数的话我们一般把它赋值给一个变量来使用

this问题

在使用箭头函数以前我们经常遇到这样的问题

const Tom = {
    name: 'Tom',
    hobbies: ['Coding', 'Sleeping', 'Reading'],
    showHobbies: function () {
        console.log(this);	// 对象 Tom 
        this.hobbies.map(function (hobby) {
            console.log(this);	// 这里我们打印一下 this 发现竟然是 Window !
            console.log(this.name + ' likes ' + hobby);
        })
    }
}

Tom.showHobbies();	
/* 输出: 
	likes Coding
	likes Coding
	likes Reading
   咦,你会发现 Tom 不见了,看来是 this.name 的 this 指向出了问题
*/

因为JS中的this是在运行的时候才绑定的,

这里的showHobbies()是由 对象Tom调用的,所以this指向的是对象Tom

map()方法里的回调函数他不是作为对象的方法调用,也没有使用applycall等方法来改变this指向,所以这里的this指向的是 Window 或者说全局(严格模式下为undefined)

以前我们通常的做法是在这之前var self = this;,然后用self代替this来使用

在ES6中我们可以借助箭头函数来代替这种 hack 写法,因为箭头函数没有自己的this,它的this值是继承它的父级作用域的(词法作用域,由上下文确定)

箭头函数不适用的场景

  1. 作为构造函数,向原型对象中添加方法
  2. 当你真的需要this的时候,例如事件绑定
  3. 需要使用arguments对象时

函数参数默认值

注意:参数中的变量是默认声明的,所以不能再函数内部再次用let或者const进行声明,这样会报错

// 直接在函数的形参后面赋值
function multiply (a = 1, b = 2) {
    return a * b;
}

multiply();		// 2
multiply(3, 5);	// 15
multiply(3);	// 6
multiply(, 5);	// error
//	一般情况下,我们使用带默认参数的函数应该是函数的最后一个参数
// 但如果非尾部的参数设置了默认值,实际上在我们调用这个函数的时候,这个参数是无法省略的
multiply(undefined, 5);	// 5
// 不能使用 null
multiply(null, 5);		// 0

模板字符串

在过去我们要组合 变量 和 字符串 的时候需要不停地用+进行连接,这样既繁琐又容易出错而且不易检查。

有了 ES6 的模板字符串就变得容易多了

模板字符串 允许我们用一对反引号 ``来定义字符串,当字符串中需要引用变量的时候只需要用${ }包裹就可以了

里面的变量可以是任意的 JS 表达式,包括对象的属性,甚至是一个函数

const name = 'Tom';
const age = 5;
const text = `${name} is ${age * 5} years old.`;

console.log(text);	// "Tom is 25 years old."

未完待续。。。

posted @ 2020-02-03 19:37  Meow的铲屎官  阅读(130)  评论(0编辑  收藏  举报