ES6新特性--常用新特性总结

1. let && const


let命令和var一样用于声明变量,但是不同的是let的作用域为局部作用域,且let声明的变量不会出现像var那样存在“变量提升”的现象,且let声明的变量不可重复。

    {
        let a = 110;
        var b = 120;
    }
    console.log(b);//b =120
    console.log(a);//a is not defined
复制代码

在函数外部可以获取到b,获取不到a,因此let适合在for循环计数器中用。

注意事项:

let不能重复声明

let不允许在相同作用域内重复声明同一个变量,即同一个作用域内不允许出现名称相同的变量。

    let a = 1;
    var a = 2;
    //像这样声明会报错:Uncaught SyntaxError: Identifier 'a' has already been declared
复制代码
    var a = 1;
    let a = 2;
    //像这样声明也会报错:Uncaught SyntaxError: Identifier 'a' has already been declared
复制代码

let的死区现象

    let a = 110;
    if(true){
        console.log(a);
        let a = 120;
        console.log(a);
    }
    //代码在第一次输出a 的时候会报错,提示a 没有定义,这就是死区效应。原因是:let不像var一样存在“变量提升现象”,所以一定要在声明后使用,否则将会报错。
复制代码

const用于声明一个常量,一旦声明,必须立即赋值,且声明后值将不会再改变。

const a;//会报错,没有立即赋值
复制代码
    const PI = 3.14159;
    PI // 3.14159
    PI = 110;//报错,常量不能被重新赋值。
复制代码

2.箭头函数


    () => 1;
    //这是一个自执行的匿名函数。等于如下代码:
    (function(){
        return 1;
    })
复制代码
//可以传参数:
    (a) => 1 + a;
    //相当于
    (function(a){
        return 1 + a;
    })
复制代码

注意:箭头函数可以说是函数的缩写,但并非完全相同,箭头函数没有constructor,没有prototype,没有this,所以>不支持new操作符,不能当做构造函数。但是箭头函数对于this的处理和其他函数不一样。箭头函数中的this始终指向函数定义时的this,而非执行的时候。也就是说箭头函数执行时,会向外层函数查找this,直到找到this就拿来为己用!

3. 模板字符串


格式为${};大括号里可以放任意的js表达式,可以进行运算,以及引用对象属性。

传统字符串的使用:

    var name = '旺财';
    var age  = 22;
    var java = function(name,age){
        var my = '我的名字是:'+ name +'\n' +
        '我今年' + age + '岁了';
        return my;
}
复制代码

而现在:

    //可多行
    var java = `我的名字是:${name}
                我今年${age}岁了`;
复制代码

模板字符串是增强版的字符串,用反引号(``)标识

    var a = 110;
    var b = 120;
    `${a} + ${b} = &{a+b}`//"110 + 120 = 230"
复制代码

也可在字符串中嵌入变量:

    let name = "老仙女",time = "today";
    `Hello ${name},今天是${time}耶!`
复制代码

模板字符串可以多行书写,模板字符串中的所有空格,新行,缩进都会原样输出在生成的字符串中。如果不想要空格换行,可以使用trim方法消除。 trim 去除字符串空格.

trim 左右空格都去掉 trimLeft 去掉左空格 trimRight 去掉右空格 使用如下:

    var str = "    a     b     c    ";
    console.log(str);//"    a     b     c    "
    console.log(str.trim());//"a     b     c"
    console.log(str.trimLeft());//"a     b     c    "
    console.log(str.trimRight());//"    a     b     c"

复制代码

repeat:构造并返回一个新的字符串,该字符串包含被连接在一起的指定数量的字符串的副本。还是看例子吧:

    var str = "12345";
    console.log(str.repeat(5));//里面的5,是指重复的遍数

    //1234512345123451234512345 这是一个新的字符串里面有5遍的12345
复制代码

includes 用来判断一个数组中是否包含一个指定的值,根据市局情况,如果包含返回true,否则返回false。如下:

    var arr = [1,2,3,4,5]
    console.log(arr.includes(1))//true
    console.log(arr.includes(6))//false

//字符串中也可用
    var str = "a bc def";
    console.log(str.includes("a"))//true
    console.log(str.includes("a b"))//true
    console.log(str.includes("bc" ))//true
    console.log(str.includes("abc"))//false
复制代码

padStrat padEnd 在开始(padStrat )/结尾(padEnd)部位填充

    var a = "hello";
    a.padStart(10,"*")//"*****hello"
    //第一个参数规定了字符串的长度,padstart就是确保字符串中的长度为n(10),若本身达不到这个长度便用第二个参数中的字符填充至n个长度。如果n<本身的长度那么输出的就是原字符串,不做改变。
    var b = "hi";
    b.padEnd(10,"*")//"hi********"
复制代码

4. 扩展运算符


扩展运算符就是三个点(...).它将一个数组转为用逗号分隔的参数序列。

    var arr = ["a","b","c"];
    var arr1 = [...arr];
    console.log(arr1)//a, b, c 
复制代码

[...arr]的作用就是把arr这个数组作为参数直接传入arr1中展开。

扩展运算符与正常的函数参数可以结合使用,非常灵活。

    var arr = [1,2,3];
    var arr1 = [4,5,6,...arr]
复制代码
    var arr = [...(a>b?[ok]:[goout]),'c'];
    //这样也是OK的
    [...[],1];
    //如果扩展运算符后面是一个空数组,则不产生任何效果。
复制代码

扩展运算符还有一个比较常用的功能是,连接两个数组。

    var arr1 = [1,2,3];
    var arr2 = [4,5,6];
    arr1.push(...arr2);
复制代码

扩展运算符还可以将字符串转为真正的数组。

    [..."hello"]
    //["h","e","l","l","o"];
复制代码
    //arguments对象
    function f(){
        let as = [...arguments];

    //NodeList对象
    [...document.querySelectorAll("li")];
    }
复制代码

5. Class(类)


前面我们都是创建构造器,然后去new构造器,构造器就相当于一个类,在ES6中,就可以使用class来创建对象了。从形式上,向主流的面向对象的语言靠拢。

注意事项:

  1. class 是关键字,后面紧跟类名,类名首字母大写,采取的是大驼峰命名法则。类名之后是{}。
  2. 在{}中,不能直接写语句,只能写方法,方法不需要使用关键字
  3. 方法和方法之间没有逗号。不是键值对

使用class来声明一个类,如下:

    class New{
        constructor(name,age){
            this.name = name;
            this.age  = age;
        }
        say(){
            console.log(`我是${this.name},今年${this.age}岁了`)
        }
    }
    var p1 = new New("小仙女","22");
    console.log(p1.say());
    //输出我是小仙女,今年22岁了
复制代码

可以说使用class是相当给力的

6. 变量的结构赋值


ES6中允许按照一定的模式,从数组和对象中提取值,对变量进行赋值。更加便利的去声明变量。

1. 数组的解构赋值


数组的解构赋值需要按照对应位置,对变量进行赋值。这种写法属于“模式匹配”,只要等是两边的模式相同,左边的变量就会被赋予对应的值。如下:

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

    let[ e, ,d] = ["hi","hello","gun"];
    e//hi
    d//gun

    let[hh,...haha] = [1,2,3,4];
    hh//1
    haha//[2,3,4]

    let [a] = [];//解构不成功,a的值就是undifined
    let [b,a] = [1];//  b//1  a的值是undifined

    let [a,b] = [1,2,3,4,5,6];//这种情况是不完全解构,对应的值是对应位置的值。
    a//1
    b//b

    let [a] = 1;//如果等号两边模式不相同,会报错。
复制代码

解构赋值允许指定默认值。注意,ES6内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undifined,默认值才会生效。如下:

    let [a = 110] = [undifined]//  a//1
    let [a = 110] = [null]//   a//null  
复制代码

如果默认值是一个表达式,那这个表达式是惰性求值的,即只有在用到的时候,才会求值。如下:

    function f(){
        console.log('aaa');
    }
    let [x = f()] = [1];
    //此时x有值,是1,所以函数f根本不会执行。等价于下面的代码:
    let x;
    if([1][0] === undefined){
        x = f();
    }else{
        x = [1][0];
    }
复制代码

2. 对象的解构赋值


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

    let {a,b} = {a:"hello",b:"hi"}
    a//hello   b//hi

    let {c} = {a:"hello",b:"hi"}
    c//undefined
复制代码

如果想变量名与属性名不一样,必须写成下面这样:

    let obj = {a:'hello',b:'hi'};
    let { a:c, b:d } = obj;
    c//hello  d//hi
复制代码

这实际说明,对象的解构赋值是下面形式的简写。

    let { a:b, c:d } = { a:"hello",c:"hi"};
复制代码

就是说,对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。对象的解构也可以指定默认值(略)。

7. Array.from


Array.from方法用于将两类对象转为真正的数组:类似数组的对象和可遍历的对象。

实例1

    var arrLike = {
        '0':'a',
        '1':'b',
        '2':'c',
        length:3
    };
    var arr1 = Array.form(arrLike);
复制代码

实例2

    var sts = document.getElementById("st");
    console.log(Array.isArray(Array.from(sts)));
    //true;
复制代码

实例3

    //arguments对象
    function f(){
        var str = Array.from(arguments);
    }
复制代码

Array.from的另一个应用是,将字符串转为数组,然后返回字符串的长度。

    function countSymbols(string){
        return Array.form(string).length;
    }
复制代码

Array..of方法用于将一组值,转换为数组。

    Array.of(2,34,45)//[2,34,45]
    Array.of(2,34,45).length//3
复制代码

8. Map && Set


Set

ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set本身是一个构造函数,用来生成Set数据结构。set不是数组,它是一个像对象的伪数组:

    var s1 = new Set();
    s1.add(1)
    s1.add(2)
    console.log(Array.isArray(s1))
    //false //说明set不是数组。
复制代码
    var ss = new Set();
    [1,12,3,4,3,1,12,3].forEach(x => s.add(x));
    for(let i of s){
        console.log(i);
        //1 12 3 4
        //上面的代码通过add方法向Set结构加入成员,结果表明Set结构不会添加重复的值。
    }
复制代码

Set函数可以接受一个数组(或者具有interable 接口的其他数据结构)作为参数,用来初始化。

    //例一
    let set = new Set([1,2,3,3,3]);
    [...set]//[1,2,3]
    //例二
    let item = new Set([1,2,3,3,3]);
    item.size //3
    //例三
    var set = new Set(document.querySelectorAll('div'));
    set.size 
复制代码
    //去掉数组的重复成员
    [...new Set(array)]
复制代码

向Set加入值的时候,不会发生类型转换,所以1和“1”是两个不同的值。Set内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),主要区别是NaN等于自身,二=而精确相等运算符认为NaN不等于自身。

Set结构的实例有一下属性。 -Set.prototype.constructor:构造函数,默认就是Set函数。 -Set.prototype.size:返回Set实例的成员总数。 Set实例的符分为两大类:操作方法和遍历方法。 四个操作方法


1. -add(value):添加某个值,返回Set结构本身。
2.-delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
3.-has(value):返回一个布尔值,表示该值是否为Set的成员。
4.-clear():清除所有成员,没有返回值。
复制代码
    s.add(1).add(2).add(2)
    s.size//2  因为2被添加了两次

    s.has(1)//true
    s.has(2)//true
    s.has(3)//false 因为s中没有3这个实例

    s.delete(2);
    s.has(2)//false 此时2这个实例已经被删除掉了。
复制代码

Array.from方法可以将Set结构转为数组。

    var item = Set([1,23,4,5]);
    var array = Array.from(items);

    //这就提供了去除数组重复的另一种方法。
    function f(array){
        return Array.from(new Set(array));
    }
    f([1,2,3,4,5,6,5,4,3,2,1])//[1,2,3,4,5,6]
复制代码

Set的四个遍历方法


1. -keys():返回键名的遍历器。
2. -values():返回键值的遍历器。
3. -entries():返回键值对的遍历器。
4. -forEach():使用回调函数遍历每个成员。
复制代码

注意:

Set的遍历顺序就是插入顺序。这个特性有时候非常有用,比如使用Set保存一个回调函数列表,调用的时候就能保证按照添加顺序调用。 keys方法,values方法,entries方法返回的都是遍历器对象。由于Set结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

    let set = new Set(['a','b','c']);

    for(let i of set.keys()){
        console.log(i);
    }//a b c

    for(let i of set.values()){
        console.log(i);
    }//a b c

    for(let i of set.entries()){
        console.log(i);
    }//['a':'a']// ['b':'b']//['c':'c']
复制代码

Set结构的实例默认可遍历,他的默认遍历器生成函数就是他的values方法。

    Set.prototype[Symbol.inerator]===Set.prototype.values
    //true
复制代码

所以,可以省略values方法,直接用for..of循环遍历Set。

    let set = new Set(['a','b','c','d']);
    for(let i of set){
        console.log(i);//a b c d
    }
复制代码

Set结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值。

    let set = new Set([1,4,7]);
    set.forEach((value, key) => console.log(key + ':' + value));
    // 1:1  4:4  7:7
复制代码

遍历的应用

扩展运算符(...)内部使用for..of循环,所以也可以用于Set结构。

    let set = new Set(['a','b','c']);
    let arr = [...set];
    //['a','b','c']
复制代码

扩展运算符和Set结构相结合,就可以去除数组的重复成员。

    let arr = [3,4,5,3,2,3];
    let sa = [...new Set(arr)];
    //[3,4,5,2]
复制代码

Map

JavaScript的对象(Object),本质上是键值对的集合,但是传统上只能用字符串当做键。这给它的使用带来了很大的限制。为了解决这个问题,ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,如果使用map,它里面的键可以是任意值。 如何创建map?如下:

    var m = new Map([
        [1,"hello"],//里面存放的键值对,1 是键,“hello”是指。
        ["a","123"],
        [true,"abc"],
        [[1,2,3],{name:"wangcai"}]//可以存放任意值
    ]);
    //注意书写格式,一不小心就会写错哟~
复制代码

使用set进行添加,如下:

    var  m = new Map([
    [1,"hello"],
    ["abc",true]
    ]);
    //通过set往集合中放入新的值
    m.set(false,"abc")
    m.set([1,2,3],{name:"wangcai"})
复制代码

还可以去获取,通过get(键),如下:

    //get(键名),得到键值
    m.get(1)
    "hello"
    m.get("abc")
    true
复制代码

但是get([1,2,3])是获取不到值,如下:

    m.get([1,2,3])
    undefined
    //原因是:get()时要比较栈区中的地址,而不是堆区中的数据。 
复制代码

解决如下:

    var m = new Map();
    m.set(true,"hello")
    let a = [1,2,3]//a保存的是[1,2,3]在堆中的地址。
    m.set(a,{name:"wangcai"})
    m.get(a);//{name:wangcai}
复制代码

重复的键会被覆盖掉,如下:

    var m = new Map();
    m.set(1,"hi")
    m.set(1,"hello")
    console.log(m)//Map(1) {1 => "hello"}
    // 如果有重复的值,后面的会把前面的覆盖掉。
复制代码

9. 严格模式


之前学习的JS,语法非常灵活,JS中这个灵活的特性,弊大于先利。后来增加了严格模式。使用严格模式的目的:规则,提高编译效率


  1. 在严格模式下不能使用没有var的变量
    "use strict"
    a = 110;
    //会报错 a is not defined
复制代码
  1. 在严格模式下不能8进制的数字
    "use strict"
    var a = 01;
    //会报错 Octal literals are not allowed in strict mode
复制代码
  1. 在严格模式下不能把函数定义在if语句中
    "use strict"
    if(true){
        function f(){
            console.log("......")
        }
        f();
    }// 会报错 f is not defined
复制代码
  1. 在严格模式下函数不能有重名的形参
    "use strict"
        function f(a,a){
            console.log("......")
        }
        f();// 会报错 Duplicate parameter name not allowed in this context
复制代码
  1. 在严格模式下arguments不再跟踪形参的变化
    "use strict"
        function f(a,b){
            console.log(a,b)  // a//1  b//2
            console.log(arguments[0],arguments[1]) //  a//1  b//2
            arguments[0] = 1111;
            arguments[1] = 2222;
            console.log(a,b) //  a//1  b//2
            console.log(arguments[0],arguments[1]) //  a//1111  b//2222
        }
        f(1,2);
复制代码
  1. 在严格模式下function中的this就不再是window
    "use strict"
        function f(){
            console.log(this)
        }
        f();//undefided
复制代码

在严格模式下,全局的变量和函数还是属于window的。

    "use strict"
    var a = 110;
    console.log(window.a)   //110
        function f(){
            console.log("...")
        }
        window.f();   //...
复制代码

严格模式也是有作用域范围的。分整个代码段和函数内。


由一个永远18岁的小仙女编写,欢迎指正~~

转载于:https://juejin.im/post/5b7001a751882560f230a9e8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值