菜鸟版ES6

201 阅读8分钟

变量

在学习ES6之前,我们所熟悉的有且仅有 var 全局变量,在学习ES6后,我们学到了新的十分实用的另外两个变量 letconst

1.三者的不同点

1.作用域

· var 是全局作用域,在函数内部和外部都可以调用使用

· let 和 const 都是块级作用域,只在声明它们的函数内部使用

2.变量提升

· var 作为全局作用域,无论它声明时“身处何方”,在使用时都会被“第一眼看到”,会被自动视为声明在函数的最顶部

· let 和 const 不存在变量提升,因此必须先声明、定义再去使用,否则会报错

3.命名规范

· var 可以重复多次定义

· let 和 const 不能重复定义,否则会报错(避免了命名污染)

4.const的特殊之处

· const 声明的变量会被认为是常量,因此const声明的变量的值是不能二次更改的(基本数据类型的值不可更改)

· 但也有特例,当 const 是对象或者数组时可以对它里面的元素进行修改(复杂数据类型的内容可以更改但是不能给它重新赋值、改变它的地址)

注意: const 在声明时必须赋值才能使用

5.let 的暂时死区

· 只要和 let 在同一块区域,这块区域就会锁定,以let关键字为先,以以下代码为例:

        var b = 10;
        if (true) {
            console.log(b);
            let b = 20;
        }

存在全局变量 b ,但是在块级作用域中 let 又声明了一个局部变量 b ,在这种情况下,使用的是 let 声明的变量,所以它的返回值应该是20

6.let 可以防止循环变量变成全局变量

以下面代码为例:

        for (let i = 0; i < 2; i++) {
            console.log(i);
        }
        console.log(i);  // i is not defined

        for (var j = 0; j < 2; j++) {
            // console.log(j);
        }
        console.log(j);

解构

1.数组解构

数组解构允许我们按照一一对应的关系从数组中提取值 然后将值赋值给变量

        let ary = [1, 2, 3];
        let [a, b, c, d, e] = ary;
        console.log(a)  // 1
        console.log(b)  // 2
        console.log(c)  // 3
        console.log(d)  // undefined
        console.log(e)  // undefined

2.对象解构

对象解构允许我们使用变量的名字匹配对象的属性 匹配成功 将对象属性的值赋值给变量

        let person = { name: 'lisi', age: 30, sex: '男' };
        // let { name, age, sex } = person;
        // console.log(name)
        // console.log(age)
        // console.log(sex)

        let { name: myName } = person;
        console.log(myName)

箭头函数

· 箭头函数是用来简化函数定义语法的

        普通写法
        function fn() {
           console.log(10);
        }
        fn();

        箭头函数写法
        const fn = () => { console.log(10) };
        fn();

· 箭头函数的可省略性

        在箭头函数中,如果函数体只有一句代码并且代码的执行结果就是函数的返回值,那么函数体的大括号可以省略不写
        const sum = (a, b) => a + b;
        const result = sum(1, 2);    // 用result去接收sum()函数计算得出来的值
        console.log(result);
        如果函数体只有一句话,那么它的 return 和 console.log() 可以省略

        同理,在箭头函数中,如果形参只有一句代码并且代码的执行结果就是函数的返回值,那么形参的小括号可以省略不写
        const fn = u => {
            alert('tell me your name');
        }
        fn();

· 箭头函数中自己没有this

        // 箭头函数中自己没有this,它的this指向包含它的区域,也就是它的this指向上下文
        // 注意:this 是静态的 this 始终指向 函数声明时 所在作用域的this值
        function fn() {
            console.log(this);    // 同样的。这也指向调用它的fn()函数
            return () => {
                console.log(this);   // 这个的this指向的是fn()函数
            }
        }
        const obj = { name: '王麻子' };
        const result = fn.call(obj);   // call()  改变this指向
        result();

· 箭头函数不能作为构造函数来实例化对象

        let Person = (name, age) => {
            this.name = name;
            this.age = age;
        }
        let you = new Person('zhangsan', 18);
        console.log(you);   // Person is not a constructor

· 箭头函数不能使用argument变量

        let fn = () => {
            console.log(argument);
        }
        fn(1, 2);  // argument is not defined

参数默认值

· ES6 允许我们给函数的形参赋值

1.初始化形参 一般是给后面的形参赋初值,如果在前面赋初值可能作用不大

当形参的位置没有传参进来,它就会使用我们手动赋给它的初值;如果有传参自然以一传入的参数来进行计算

        function add(a, b, c = 5) {
            return a + b + c;
        }
        let result = add(1, 2);
        console.log(result);

2.与解构赋值结合使用

       function connect({ host, user, password, part }) {
            console.log(host);
            console.log(user);
            console.log(password);
            console.log(part);
        }
        connect({
            host: 'lf.mic',
            user: 'root',
            password: 'root',
            part: 1101
        })     // 调用函数并传参进去

rest参数和拓展运算符

· rest 参数

rest 参数的使用和扩展运算符的运算几乎是一模一样

rest 参数表示: ...

rest 参数用于获取实参 代替了arguments (ES6时期引入的)

注意:argument 是一个对象因此它的返回值也是一个对象 rest 参数返回值是一个数组,因此可以使用数组的相关应用(filter、some等)

        // 比较:
        // ES5 获取参数的方法
        // function data() {
        //     console.log(arguments);
        // }
        // data('小张张', '真源儿', '笨蛋真源');

        // ES6 获取参数
        // function data(...args) {
        //     console.log(args);
        // }
        // data('小张张', '真源儿', '笨蛋真源');

        // rest 参数必须放在最后
        function fn(a, b, ...c) {
            console.log(a);
            console.log(b);
            console.log(...c);
        }
        fn(1, 2, 3, 4, 5, 6, 7, 8, 8, 9);
        // 不同点:1.它的结果不会以逗号分隔而是直接输出来
        // 2.rest 参数是放在函数形参的位置,而扩展运算符是放在函数传参的位置,即实参的位置

· 扩展运算符

扩展运算符表示: ...

1.扩展运算符可以用来合并数组

        // 方法一:新建一个数组
        // let arr1 = [1, 2, 3, 4];
        // let arr2 = [5, 6, 7];
        // let arr3 = [...arr1, ...arr2];
        // console.log(arr3);

        // 方法二:利用push方法,因为push方法中的对象也是用逗号分隔开来的,所以可用于合并数组
        // let arr1 = [1, 2, 3, 4];
        // let arr2 = [5, 6, 7];
        // arr1.push(...arr2);
        // console.log(arr1);

2.扩展运算符可以将伪数组转换为真正的数组,从而就可以使用数组的便捷方式

        var oDivs = document.getElementsByTagName('div');
        console.log(oDivs);    // 此时它还是伪数组的形式
        var arr = [...oDivs];
        console.log(arr);    // 此时它已经是真正的数组了
        arr.push(1);
        console.log(arr);

Symbol

· Symbol创建的变量是唯一的

创建方法:

        // 创建 Symbol
        // 1.直接创建
        let s = Symbol();
        // console.log(typeof s);  // symbol

        // 2.传参进去 (里面的参数就相当于一个标志,因此即使有其他的Symbol类型的值里面的描述字符串是一样的,他们的地址也是不一样的,“值”实际上也是不一样的)
        let s2 = Symbol('尚硅谷');
        let s3 = Symbol('尚硅谷');      // 这里的Symbol是一个函数
        console.log(s2 === s3);   // false

        // 3.Symbol.for 方法创建
        let s4 = Symbol.for('尚硅谷')     // 此时这里的Symbol是一个对象 ,因此我们称 Symbol.for() 为:函数对象
        let s5 = Symbol.for('尚硅谷')
        // 通过这种方法创建的它的“地址”是一样的
        console.log(s4 === s5);   // true

        // 注意:Symbol 不能与其他数据进行运算(对比、比较也不可以!)

· Symbol 可以为对象添加属性和方法

        // let game = {
        //     name: '俄罗斯方块'
        // }
        // 方法一:
        // 声明一个对象
        // let methods = {
        //     up: Symbol(),
        //     down: Symbol()
        // };
        // // 给对象属性赋值
        // game[methods.up] = function () {
        //     console.log('上上上上');
        // }
        // game[methods.down] = function () {
        //     console.log('下下下下');
        // }
        // console.log(game);

        // 方法二:
        let yule = {
            name: '微博',
            [Symbol('active')]: function () {
                console.log('发微博了!');
            },
            [Symbol('happyTime')]: function () {
                console.log('张哥的清唱时刻');
            }
        }
        console.log(yule);

模板字符串

模板字符串:ES6 新增的创建字符串的一种方式,使用 `` 反引号进行定义

· 模板字符串可以解析变量

        // let set = ` 这是一个模板字符串 `;
        // console.log(set);

        // let name = `张三`;
        // let say = `嗨害,我是${name},你好呀`;
        // console.log(say);
        // 注意:是 `` 反引号 不是引号,符号不同,表达效果也截然不同

· 模板字符串可以换行

        //     let msg = {
        //         name: `李四`,
        //         age: 18
        //     };
        //     let html = `
        // <div>
        //     <span>${msg.name}</span>
        //     <span>${msg.age}</span>
        //     </div>
        // `;
        //     console.log(html);

· 模板字符串可以调用函数,也可以直接进行变量拼接

        const fn = () => {
            return "又要上课了,真开心";
        }
        let a = `六点一十了已经,${fn()}`;
        console.log(a);

        // ${} 是用来调用模板字符串的
        // 注意:在单引号和双引号中书写的内容是不允许有换行的存在的,但是模板字符串内部可以换行

Set数据结构和Map数据结构

· set 数据结构 类似于数组,但是它的值都是唯一的

具体代码如下,请仔细观看:

        // set 本身是一个构造函数 因此可以用来生成数据结构
        // 注意:因为是构造函数,所以需要实例化对象 new 一下
        // const s1 = new Set();
        // console.log(s1.size);
        // const 只阅读不能更改,可以一定程度的将它看作一个常量,当然声明常量用的就是它
        // size 判断内容的长度

        // set 函数可以接受一个数组作为参数,用来初始化
        // const s2 = new Set(['a', 'b', 'c', 'd']);
        // console.log(s2);
        // console.log(s2.size);

        // // set 会自动去重 因此可以用作数组去重
        // const s3 = new Set(['a', 'a', 'c', 'c']);
        // // console.log(s3.size);    // 2
        // let arr = [...s3];
        // console.log(arr);   // a c
        // // 运用扩展运算符将s3里面的所有数据获取过来,并且将其转换为数组形式输出

        // set.add() 增 返回数组本身
        const s4 = new Set();
        s4.add('a').add('d');  // 可链式调用
        console.log(s4.size);

        // set.delete() 删 返回的是布尔值
        const r1 = s4.delete('a');
        console.log(s4.size);
        console.log(r1);    // true

        // set.has() 查 检查数组中是否有检索的元素  返回的是布尔值
        const r2 = s4.has('b');
        console.log(r2);

        // set.clear() 清空所有内容  无返回值
        s4.clear();
        console.log(s4.size);

        // 利用forEach()遍历set数据结构 从而获取值
        const s5 = new Set(['a', 'b', 'c']);
        s5.forEach(value => {
            console.log(value);
        })

        // 注意:set 输出结果仍是以数组形式  因此它里面的数据类型还是有影响的,例如:数字型的值和字符串类型的值是不一样的,因此即使set有自动去重的功能,数据类型不同的两个数还是不会被删除的

· map 数据结构 类似于对象 是以键值对的方式来进行运算的 可以说它是键值对的集合,各个类型的值(包括对象)都可以用来当作键

具体代码如下,请仔细观看:

        //  map 与 set 相同,也是构造函数,可以用来生成数据结构

        // 变量.set() 增
        const a = new Map();
        a.set('name', ['宋柏彦', '唐黎']);
        a.set('age', 32);
        a.set('sex', '男');
        console.log(a.size);

        // 变量.set() 改
        // 当之前已经存在的元素“再次出现” set 就是 承担一个“改”的角色,将之前的数据覆盖,使之始终呈现最新的数据
        a.set('age', 24);
        // console.log(a);

        // 变量.delete() 删
        console.log(a.delete('age'));
        // 返回值是 true 和 false

        // 变量.get() 查
        console.log(a.get('name'));

        // 变量.clear() 清空所有数据
        a.clear();
        console.log(a);

        // 练习
        // 1.判断代码的输出值
        const set = new Set();
        set.add(1);
        set.add(1);
        set.add('1');
        console.log(set);  // 返回值是 1 '1'  两个1的类型不同

        // 2.创建一个map 添加以下数据: 1:"北京"  2:"上海"  3:"湖南" 并且删除第一个元素
        const cities = new Map();
        cities.set(1, "北京");
        cities.set(2, "上海");
        cities.set(3, "湖南");
        // console.log(cities);
        cities.delete(1);
        console.log(cities);

至此,小编目前学习的有关ES6的大部分知识以总结完了,小编正在“快马加鞭”的学习,光看不过瘾,赶紧动手来试试吧,没有什么解说能够代替亲身体验

5652641F6046387C074EA0036E6B0126.jpg

如有错误,请在评论区中指正,我们共同进步!

7C9DF58016B4A80C33909B8EEEC915EA.gif