es6(二)

来源:互联网 发布:剑与魔法坐骑进阶数据 编辑:程序博客网 时间:2024/06/02 18:49

es6(二)

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

  • es6在2017年可谓是大火,被越来越多的人频频提及,在React、ReactNative开发中广泛使用。javascript在es6的推出后,是越来越健全,真不能认为它是一个”玩具语言”啦。haha
    较为深入的学习es6是非常有必要的,我总结了一些es6相关的语法特性及较为详细的使用说明,其中还有一些学习心得,希望可以给大家带来帮助。

一、解构赋值

1.数组的解构

数组下标顺序对应

    var [a, b, c] = [1, 2, 3];    console.log(a, b, c); // 1, 2, 3

还可以不完全解构

    var [a, , c] = [1, 2, 3];    console.log(a, c); // 1, 3

适用于嵌套解构

    var [a, b, c, d] = [1, 2, 3, [4, 5]];    console.log(a, b, c, d); // 1, 2, 3, [4, 5];
    var [a, b, c, [d, e]] = [1, 2, 3, [4, 5]];    console.log(a, b, c, d, e); // 1, 2, 3, 4, 5;

配合rest运算符,可将数组末尾元素都收集起来,只能放在末尾

    var [a, b, c, ...d] = [1, 2, 3, 4, 5];    console.log(a, b, c, d); // 1, 2, 3, [4, 5];

只要右边是可遍历解构(数组,迭代器,类数组)都能够结构成功。

2.对象的解构

变量属性名对应

    var {a, b, c} = {a: 1, b: 2, c: 3};    console.log(a, b, c); // 1, 2, 3

还可以设置模式(别名)

    var {a: A, b: B, c: C} = {a: 1, b: 2, c: 3};    console.log(A, B, C); // 1, 2, 3

这时候a, b, c分别是”模式”,解构去匹配符合格式的对象结构。它先找到同名属性,然后再赋值给对应的变量。
真正被赋值的是后面的A、B、C,所以A、B、C 也可以称作a、b、c的别名。
这有一个特殊情况

    let a = 2;    ({a} = {a: 1}) // 不能写成 {a} = {a: 1}    console.log(a) // 1

如果有一个变量前面定义过,现在想给他重新赋值,就需要把{a} = {a: 1}用小括号包裹起来,这个是js解析引擎的一个问题

3.字符串的解构

    let {a, b, c} = 'hello';    console.log(a, b, c) // 'h', 'e', 'c'

字符串也可看作是特殊的数组, 满足所有数组的操作

4.可设置初始值

    let {a, b, c, d = 5} = {a: 1, b: 2, c: 3};    console.log(a, b, c, d) // 1, 2, 3, 3

数组也是一样的

5.复杂的解构操作

    let obj = {        bar: 'xxx',        foo: {            arr: [                'hello',                {a: 1}            ],            baz: 1        }    }    let { foo: { arr: [x, {a}], baz}, bar} = obj;    console.log(x, a, baz, bar); // 'hello', 1, 1, 'xxx'

hah, 是不是很绕,面对这种复杂结构的解构,我们只要记住一句话

数组找下标,对象找同名属性

就ok啦。

6.解构在函数参数中的使用

    function foo({a, b, c, d=2}){        console.log(a, b, c, d); // 1, 2, 3, 2    }    foo({a: 1, b: 2, c: 3});

其实理解了数组和对象的解构,在哪都能灵活运用啦。

7.交换变量的值

    var a = 1, b = 2;    [b, a] = [a, b];

二、扩展运算符(spread)和rest运算符

扩展运算符(spread)也叫圆点运算符(…),他的作用是,遍历目标对象,输出所有结果。
所以只要是能够遍历的数据结构如(数组、类数组、迭代器、对象),都能够使用(…)进行操作。

1.数组/对象浅拷贝

    let arr = [1, 2, 3, 4];    let newArr = [...arr];    console.log(arr === newArr); // false    let obj = { a: 1, b: 2};    let newObj = { ...obj};    console.log(obj === newObj); // false

利用圆点操作符,可以快速进行浅拷贝,非常的优雅。
但对于复杂的对象、数组结构,该操作无法拷贝深层的数据,所以强调这只是浅拷贝

2.合并数组、对象

    let arr1 = [1, 2];    let arr2 = [3, 4];    let newArr = [...arr1, ...arr2];    console.log(newArr); // 1, 2, 3, 4    let obj1 = { a: 1, b: 2};    let obj2 = { a: 3, c: 2};    let newObj = { ...obj1, ...obj2};    console.log(newObj); // { a: 3, b: 2, c: 2};

由此就可以引申出各种神奇操作,还需要我们在平时慢慢摸索,在这里就不一一介绍了。

3.rest运算符

rest运算符实质上相当于spread的反例,不知道还记不记得上面的一个例子

    function foo(...arg){        console.log(arg); // 相当于arguments    }

可以知道rest实质上就是把剩余参数作为数组元素收集起来

三、字符串扩展方法

1.模板字符串

使用反引号(“),可以保留字符串的格式,空格回车,使用(${})来引入变量

    // 模板字符串    var a = 1;    var str = `sss    hello world${a}`;    // 普通字符串    var a = 1;    var str = 'sss'    + 'hello world' + a;

2.includes 、startsWidth、endsWidth

传统上,javascript中只有indexOf方法可以用来确定两个字符串的包含关系,es6提出了三个方法来帮助我们分析两个字符串的关系
1. includes : 返回布尔值,表示是否找到了参数字符串
2. startsWidth : 返回布尔值,表示参数字符串是否在源字符串的头部
3. endsWidth : 返回布尔值

    var s = 'hello world!';    s.includes('lo wo'); // true    s.startsWidth('he'); // true    s.endsWidth('d!'): // true

他们还包含第二个参数,表示开始搜索的位置。

    var s = 'hello world!';    s.includes('world', 6); // false    s.startsWidth('world', 6); // true    s.endsWidth('world', 5): // true

3.padStart、padEnd

padStart(n, s);
表示在目标字符串头、尾不停插入字符串s,并使插入完成后的字符串长度为n

    'x'.padStart(8, 'ab'); // 'abababax'    'x'.padEnd(2, 'ab'); // 'xab'
  • 如果原字符串的长度大于指定的n的长度,则会返回原字符串
  • 如果第二个参数的默认值为空格

4.repeat

repeat(n)
表示将目标字符串重复n此,并将他作为结果返回

    'x'.repeat(5); // 'xxxxx'

四、Number的扩展

1.进制转换

在之前的版本,进制转换通常用

    let num = 5;    console.log(num.toString(2)); // 十进制转换为二进制    let num2 = 101;    console.log(parseInt(num2, 2)); // 二进制转换为十进制

这些写法非常的不好记而且麻烦,现在es6为我们提供了一些新方法

    let num3 = 0B101; // 表示二进制 0B 或 0b    let num4 = 0O101; // 表示八进制 0O 或 0o

2.Number.isFinite

isFinite 用来检查 是否非无穷

    Number.isFinite(5); // true    Number.isFinite('5'); // false    Number.isFinite(Infinity); // false

3.es6一些方法被移植到Number对象上

如 isNaN、parseInt、parseFloat、isInteger
行为完全不变,这样做的目的,是逐步减少全局性方法,使语言逐步模块化。

4.安全整数和Number.isSafeInteger

js能够准确表示的整数范围在-2^53 到 2^53 之前(不包含两个端点)

    Number.MAX_SAFE_INTEGER; // 9007199254740991    Number.MIN_SAFE_INTEGER; // -9007199254740991

5.Math中新增非主流方法

    Math.trunc(5.5); // 取整 5    Math.sign(5); // 1    Math.sign(0); // 0    Math.sign(-5); // -1

sign用来判断是否为正数、负数、零。

五、函数的扩展

箭头函数单独拎出来提过啦
所以说说别的

1.参数默认值

    function foo(x=5, y){        // 传入的参数只要等于undefined或者不传入参数,就会取走默认值    }

配合解构赋值食用风味更佳

2.foo.length返回的是没有默认值的参数的个数

3.foo.name返回的是函数的名字

4.严格模式(use strict)

  • ES6:规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式, 否则会报错。
    1. 全局变量必须显示声明
    2. 禁止this关键字指向全局对象 构造函数必须new
    'use strict';    function People(name, age){        this.name = name;        this.age = age;    }    People('lisi', 18); // Cannot set property 'name' of undefined
  1. 对象不能有重复属性
  2. 函数不能有重名参数
  3. 禁止使用with
    'use strict';    let a = 1;    let b = {        a: 2    }    with(b){        console.log(a);    }    // strict mode code may not include a with statement
  1. 禁止使用arguments.callee

五、数组的扩展

1.Array.from

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。

类数组的对象
    let arrayLike = {        '0': 'a',        '1': 'b',        '2': 'c',        length: 3    };    // ES5的写法    var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']    // ES6的写法    let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
NodeList 转化为数组的方法
    let ps = document.querySelectorAll('p'); // NodeList 类型 类数组    let arr = [...ps];    let arr2 = Array.from(ps);    let arr3 = [].slice.call(ps); // 实例方法    //  arr3 = Array.prototype.slice.call(ps); // 类方法    let arr4 = arr4.constructor;

2.Array.of

将一堆元素转化为数组

    let arr = new Array(1,2,3,4); // [1,2,3,4]    let arr2 = new Array(3); // [empty × 3]    let arr3 = Array.of(3); // [3]

3.copyWithin

  1. target(必需):从该位置开始替换数据。
  2. start(可选):从该位置开始读取数据,默认为0。如果为负值,表示倒数。
  3. end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。
    [1, 2, 3, 4, 5, 6].copyWithin(0, 3, 4); // 4, 2, 3, 4, 5, 6

4.find 和 findIndex

find用于找出第一个符合条件的数组成员。

    [1, 2, 3, 4, 5, 6].find((item, key, arr) => (item > 3)) // 4

findIndex返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。

    [1, 2, 3, 4, 5, 6].find((item, key, arr) => (item > 3)) // 4

5.includes 与 字符串的类似

6.entries,keys 和 values 与迭代器的类似

entries 可用next()执行, 适用于不规则输出的情况

    let letter = ['a', 'b', 'c'];    let entries = letter.entries();    console.log(entries.next().value); // [0, 'a']    cosole.log(123);    console.log(entries.next().value); // [1, 'b']    cosole.log(456);    console.log(entries.next().value); // [2, 'c']

7.for of遍历

    for(let item of arr){        console.log(item); // 内容    }    for(let item of arr.keys()){        console.log(item); // 索引    }    for(let [index, item] of arr.entries()){        console.log(item, index); // 内容 + 索引    }

8.其他遍历方法

  1. forEach():没有返回值,只是针对每个元素调用func
  2. map():返回一 个新的Array,每个元素为调用func的结果
  3. filter():返回一个符合func条件的元素数组
  4. some():返回一个boolean,判断是否有元素是否符合func条件
  5. every():返回一个boolean,判断每个元素是否符合func条件