Home / Blog / it

ES6学习笔记

Author: Vic.Wang 2017/06/21 Tags:javascriptjswebes6es2015esmascriptes6学习es6入门

之前看过几遍阮一峰的《ECMAScript 6 入门》,但是不经常用,看了就忘。

这次看的时候决定好好记些笔记,方便日后翻看。

ES6声明变量的六种方法:

  • var
  • function
  • let
  • const
  • import
  • class

ES5只有两种声明变量的方法:var 和 function 命令。

let:声明变量

    let a = 'NLX';
                    
  • let声明的变量只在代码块中有效
  • 变量声明后使用,不然报错
  • let不存在变量提升
  • 处于暂时性死区的变量,用 typeof 会报错
  • 在同一代码块中,let不允许重复声明变量

外部有同名变量,代码块内let又声明了该同名变量,则该变量在声明前不可被赋值,必须先声明后使用。

在用 let 声明变量之前使用该变量,从使用到声明这中间的过程就叫暂时性死区,会报错。

块级作用域

    {
      let a = 'NLX';
      let f = function () {
        retuan a;
      }
    }
                    
  • 不同代码块,声明的同名变量不受影响
  • 块级作用域可以任意嵌套
  • let声明的变量,外层作用域无法读取内层作用域
  • 块级作用域中可以声明函数,但当前作用域外无法使用
  • 块级作用域声明函数,存在兼容问题,应使用函数表达式

const: 声明只读常量

    const PI = 3.1415;
                    
  • const声明的常量是只读的,一旦声明就不能改变
  • const声明的常量,声明时必须赋值
  • 只在声明所在的块级作用域中有效
  • const不存在常量提升
  • const也有暂时性死区
  • 在同一代码块中,const也不可重复声明
  • 不可赋值给其他变量
  • 声明的变量是个对象或数组,可修改但不可赋值

顶层对象的属性

顶层对象,在浏览器环境指的是window对象,在Node指的是global对象。

ES5之中,顶层对象的属性与全局变量是等价的。

var命令和function命令声明的全局变量,依旧是顶层对象的属性。

let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。

变量的解构赋值

ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被成为解构。

1、数组的解构赋值

  • 模式匹配,只要等号两边的模式相同,左边的变量就会被赋予对应的值。
  • 不完全匹配,等号左边的模式,只匹配一部分等号右边的数组。
  • 解构不成功,变量的值等于undefined。
  • 等号右边不是数组(严格地说不是可遍历的结构)将会报错。
  • Set结构,也可以使用数组的解构赋值。
  • 解构赋值允许指定默认值。

1.1 模式匹配

    let [a, b, c] = [1, 2, 3];
    a //1
    b //2
    c //3

    let [foo, [[bar], baz]] = [1, [[2], 3]];
    foo //1
    bar //2
    baz //3

    let [ , , third] = ['foo', 'bar', 'baz'];
    third //'baz'

    let [x, , y] = [1, 2, 3];
    x //1
    y //3

    let [head, ...tail] = [1, 2, 3, 4];
    head //1
    tail //[2, 3, 4]

    let [x, y, ...z] = ['a'];
    x //'a'
    y //undefined
    z //[]
                    

1.2 解构不成功

    let [foo] = [];
    foo //undefined

    let [bar, foo] = [1];
    foo //undefined
                    

1.3 不完全匹配

    let [x, y] = [1, 2, 3];
    x //1
    y //2

    let [a, [b], d] = [1, [2, 3], 4];
    a //1
    b //2
    d //4
                    

1.4 指定默认值

    let [foo = true] = [];
    foo //true

    let [x = 1] = [undefined];
    x //1

    let [x = 1] = [null];
    x //null
                    

注意,ES6 内部使用严格相等运算符(===),判断一个位置是否有值。所以,如果一个数组成员不严格等于undefined,默认值是不会生效的。

2、对象的解构赋值

解构不仅可以用于数组,还可以用于对象。

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

    let { foo, bar } = { foo: 'aaa', bar: 'bbb' };
    foo //'aaa'
    bar //'bbb'

    let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
    foo //'aaa'
    bar //'bbb'

    let { baz } = { foo: 'aaa', bar: 'bbb' };
    baz //undefined
                    

对象的解构指定默认值

    var {x = 3} = {};
    x //3

    var {x, y = 5} = {x: 1};
    x //1
    y //5
                    

3、字符串的解构赋值

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。

    const [a, b, c, d, e] = 'hello';
    a //'h'
    b //'e'
    c //'l'
    d //'l'
    e //'o'

    let {length : len} = 'hello';
    len //5
                    

4、数值和布尔值的解构赋值

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

5、函数参数的解构赋值

    function add([x, y]) {
      return x + y;
    }
    add([1, 2]); //3
                    

字符串的扩展

  • includes():返回布尔值,表示是否找到该字符串
  • startsWith():返回布尔值,表示字符串是否在源字符串头部
  • endsWith():返回布尔值,表示字符串是否在源字符串尾部
    var s = 'mingsixue';
    s.includes('ing'); //true
    s.startsWith('ming'); //true
    s.endsWith('xue'); //true
                    

这三个方法都支持第二个参数,表示开始搜索的位置。

使用第二个参数n时,endsWith的行为和其他两个方法有所不同,它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。

  • repeat()方法返回一个新字符串,表示将原字符串重复n次。
    'x'.repeat(3); //'xxx'
    'xue'.repeat(2); //'xuexue'
                    
  • padStart():在头部补全指定的字符串长度
  • padEnd():在尾部补全指定的字符串长度
    'xue'.padStart(7, 'love'); //lovexue
    'love'.padEnd(7, 'xue'); //lovexue
                    

接受2个参数,第一个参数用来指定字符串的最小长度,第二个参数时用来补全的字符串。

如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。

如果用来补全的字符串与原字符串,两者的长度之和超过了指定的最小长度,则会截去超出位数的补全字符串。

如果省略第二个参数,默认使用空格补全长度。

模板字符串

模板字符串用反引号(`)标识,可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

模板字符串中嵌入变量,需要将变量名写在${}之中。

大括号内部可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性,还可以调用函数。

    var name = 'vic';
    `Hello ${name}`;
                    

正则的扩展:

u 修饰符

ES6对正则表达式添加了 u 修饰符,含义为“Unicode模式”,用来正确处理大于 \uFFFF 的Unicode字符,也就是说,会正确处理四个字节的UTF-16编码。

u 修饰符的影响

  • 点字符(.),对于码点大于0xFFFF的Unicode字符,点字符不能识别,必须加上 u 修饰符。
  • 新增大括号表示Unicode字符,这种表示法在正则表达式中必须加上u修饰符,才能识别当中的大括号,否则被解读为量词。
  • 使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的Unicode字符
  • 也影响预定义模式,能否正确识别码点大于0xFFFF的Unicode字符

y 修饰符

新增y修饰符,作用与g修饰符类似,都是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始。不同之处在于,g修饰符只要剩余位置中存在匹配即可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。

sticky 属性

与y修饰符相匹配,ES6的正则对象多了sticky属性,表示是否设置了y修饰符

    var r - /hello\d/y;
    r.sticky; //true
                    

flags 属性

ES6为正则表达式新增了flags属性,会返回正则表达式的修饰符。

    /abc/ig.flags;  //'gi'
                    

数值的扩展:

isFinite()方法

ES6在Number对象上,新提供了Number.isFinite()方法,用来检查一个数值是否为有限的(finite)。

    Number.isFinite(15); //true
    Number.isFinite(0.8); //true
    Number.isFinite(NaN); //false
    Number.isFinite(Infinity); //false
    Number.isFinite(-Infinity); //false
    Number.isFinite('foo'); //false
    Number.isFinite('15'); //false
    Number.isFinite(true); //false
                    

isNaN()方法

Number.isNaN()用来检查一个值是否为NaN。

    Number.isNaN(NaN); //true
    Number.isNaN(15); //false
    Number.isNaN('15'); //false
    Number.isNaN(true); //false
    Number.isNaN(9/NaN); //true
    Number.isNaN('true'/0); //true
    Number.isNaN('true'/'true'); //true
                    

它们与传统的全局方法isFinite()和isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。

    isFinite(25) // true
    isFinite("25") // true
    Number.isFinite(25) // true
    Number.isFinite("25") // false

    isNaN(NaN) // true
    isNaN("NaN") // true
    Number.isNaN(NaN) // true
    Number.isNaN("NaN") // false
    Number.isNaN(1) // false
                    

isInteger()方法

Number.isInteger()用来判断一个值是否为整数。需要注意的是,在 JavaScript 内部,整数和浮点数是同样的储存方法,所以3和3.0被视为同一个值。

    Number.isInteger(25) // true
    Number.isInteger(25.0) // true
    Number.isInteger(25.1) // false
    Number.isInteger("15") // false
    Number.isInteger(true) // false
                    

Math对象的扩展

Math.trunc()

Math.trunc方法用于去除一个数的小数部分,返回整数部分。

对于非数值,Math.trunc内部使用Number方法将其先转为数值。

对于空值和无法截取整数的值,返回NaN。

    Math.trunc(4.1) // 4
    Math.trunc(4.9) // 4
    Math.trunc(-4.1) // -4
    Math.trunc(-4.9) // -4
    Math.trunc(-0.1234) // -0

    Math.trunc('123.456'); // 123

    Math.trunc(NaN); // NaN
    Math.trunc('foo'); // NaN
    Math.trunc(); // NaN
                    

Math.sign()

Math.sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。

它会返回五种值。

  • 参数为正数,返回+1
  • 参数为负数,返回-1
  • 参数为0,返回0
  • 参数为-0,返回-0
  • 其他值,返回NaN
    Math.sign(-5) // -1
    Math.sign(5) // +1
    Math.sign(0) // +0
    Math.sign(-0) // -0
    Math.sign(NaN) // NaN
    Math.sign('9'); // +1
    Math.sign('foo'); // NaN
    Math.sign(); // NaN
                    

函数的扩展

函数参数的默认值

ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。

    function log(x, y = 'World') {
      console.log(x, y);
    }
                    

参数变量是默认声明的,所以不能用let或const再次声明。

rest参数

ES6引入了rest参数(形式为...变量名),用于获取函数得多余参数。rest参数搭配得变量是一个数组,将多余的参数放入数组中。

rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。

    function add(...values) {
      let sum = 0;

      for (var val of values) {
        sum += val;
      }

      return sum;
    }

    add(2, 5, 3); //10
                    

name属性

函数的name属性,返回该函数的函数名。

箭头函数

ES6允许使用“箭头”( => )定义函数。

    var f = v => v;

    //上面的箭头函数等同于:

    var f = function(v) {
      return v;
    }
                    

如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。

    var f = () => 5;
    //等同于
    var f = function () { return 5; };

    var sum = (num1, num2) => num1 + num2;
    //等同于
    var sum = function(num1, num2) {
      return num1 + num2;
    }
                    

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

    var sum = (num1, num2) => { return num1 + num2; }