JavaScript 高级五 let; const;解析赋值;箭头函数;剩余参数;Array的扩展方法;String的扩展方法;set 数据结构

ES6 简介

ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范

ES6 实际上是一个泛指,泛指 ES2015 及后续的版本。

每一次标准的诞生都意味着语言的完善,功能的加强。JavaScript语言本身也有一些令人不满意的地方。

  1. 变量提升特性增加了程序运行时的不可预测性
  2. 语法过于松散,实现相同的功能,不同的人可能会写出不同的代码

1.0 ES6 的新增语法

1.1 关键字 let

ES6中新增的用于声明变量的关键字-------let。(let声明的变量只在所处于的块级有效)

    <script type="text/javascript">
        /* --------let关键字就是用来声明变量的-------- */
        let a = 10;
        console.log(a);

        /* --------使用let关键字声明的变量具有块级作用域-------- */
        if (true) {
            let b = 20;
            console.log(b)
            if (true) {
                let c = 30;
            }
            console.log(c);
        }
        console.log(b)

        /* -------在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的--------- */
        if (true) {
            let num = 100;
            var abc = 200;
        }
        console.log(abc);
        console.log(num)


        /* -------防止循环变量变成全局变量--------- */
        for (let i = 0; i < 2; i++) {} // 在小括号中使用 let 声明的变量 也是与for 循环绑定  类似在中括号中。
        console.log(i); // i = 2   因为只有 i = 2 时 这个才不成立


        /*-----使用let关键字声明的变量没有变量提升------*/
        console.log(a);
        let a = 100; //  会报错


        /* -------使用let关键字声明的变量具有暂时性死区特性------- */
        var num = 10
        if (true) {
            console.log(num); // 这个跟上一个一样 报错, 因为这个 num是找的下一级, 在if中声明 let 与 if 绑定
            let num = 20;
        }
    </script>

**注意:**使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性。

1.1 关键字 变量 let–面试题

    <script type="text/javascript">
        // 这个题的关键点在于变量 i 是全局变量, 函数执行是输出的都是全局作用域下的值。
        var arr = [];
        for (var i = 0; i < 2; i++) { // 如果用 var 声明  由于里面是函数, 无法自动执行,  所以会一直循环到 i 等于 2, 然后再去看下面的调用  所以两个结果都是 2 
            arr[i] = function() { //    	
                console.log(i);
            }
        }
        arr[0](); // 2
        arr[1](); // 2

        // 此题的关键点在于每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的。
        // 函数执行时输出的是自己的上一级( 循环产生的块级作用域) 下的 i 值。
        let arr = [];
        for (let i = 0; i < 2; i++) {
            arr[i] = function() {
                console.log(i);
            }
        }
        arr[0]();
        arr[1]();
    </script>

1.2 常量 const

作用:声明常量,常量就是值(内存地址)不能变化的量。

    <script type="text/javascript">
         1. 使用const关键字声明的常量具有块级作用域
        // if (true) {
        // 	const a = 10;
        // 	if (true) {
        // 		const a = 20;
        // 		console.log(a);
        // 	}
        // 	console.log(a);
        // }
        // console.log(a);
        
         2. 使用const关键字声明的常量必须赋初始值
        // const PI = 3.14;

        3.  常量声明后值不可更改 
        const PI = 3.14;
        // PI = 100;
        const ary = [100, 200];
        ary[0] = 123; //  这个是对的 ,  123 200   所以对于复杂数据类型,他内部的值是可以更新的 
        ary = [1, 2] //  这个是错的               但是却不能重新赋值
        console.log(ary);
    </script>

1.3 let、const、var的区别

  1. 使用 var 声明的变量,其作用域为 该语句所在的函数内,且存在变量提升现象
  2. 使用 let 声明的变量,其作用域为该语句所在的代码块内,不存在变量提升。
  3. 使用 const 声明的是常量,在后面出现的代码中不能再修改该常量的值。
    变量提升 就是 var 可以预解析到 script 顶部。简而言之 let 的console.log不能写在他前面。

2.0 解构赋值

ES6中允许从数组中提取值,按照对应位置,对变量赋值。对象也可以实现解构。

按照一定模式,从数组中或对象中提取值,将提取出来的值赋值给另外的变量。

2.1 数组解构

    <script type="text/javascript">
        // 数组解构允许我们按照一一对应的关系从数组中提取值 然后将值赋值给变量
        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    如果解构不成功,变量的值为undefined。
        console.log(e) // undefined
    </script>

2.1 对象解构

    <script type="text/javascript">
        // 对象解构允许我们使用变量的名字匹配对象的属性 匹配成功 将对象属性的值赋值给变量
		方法一
        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;  // 这个的意思是  把 lisi 赋值给 myName 这个变量
        console.log(myName) // lisi
    </script>

3.0 箭头函数

ES6中新增的定义函数的方式


		() => {} 
		const fn = () => {}
		fn();

函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号

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

如果形参只有一个,可以省略小括号

		function fn (v) {
			 return v; 
		}
		const fn = v => v;

最后也可以两个括号都省略。

箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this。

        function fn() {
            console.log(this);
            return () => {
                console.log(this) 
       // 因为箭头函数在 fn 函数中,fn函数指向的是 obj 对象,所以箭头函数也是指向 obj 对象
            }
        }
        const obj = {
            name: 'zhangsan'
        };
        const resFn = fn.call(obj);
        resFn();

3.0 箭头函数-- 面试题

    <script type="text/javascript">
        var age = 100;
        var obj = {
            age: 20,
            say: () => {
                alert(this.age)
         // obj 是一个对象,不能产生作用域, 所以他里面的属性是全局变量 
        // 所以如果没有var age = 100; this的指向是window,window下没有age属性,为空。
        // 而加了 var age  window下就有了 age属性了
            }
        }
        obj.say(); //  100
    </script>

4.0 剩余参数

剩余参数语法允许我们将一个不定数量的参数表示为一个数组。

    <script type="text/javascript">
        const sum = (...args) => {    // ...args 表示了所有的参数
            let total = 0;
            args.forEach(item => total += item); //这个就是遍历所有参数 并使他们相加
            return total;
        };
        console.log(sum(10, 20));
        console.log(sum(10, 20, 30));


        let ary1 = ['张三', '李四', '王五'];
        let [s1, ...s2] = ary1;
        console.log(s1) // 这个 就是得到 张三
        console.log(s2) // 前面加 ...  s2 就变成了数组  里面放了 李四和王五

5.0 Array 的扩展方法

5.1 扩展运算符(展开语法)

1.扩展运算符可以将数组或者对象转为用逗号分隔的参数序列。

2.扩展运算符可以应用于合并数组。

3.将类数组或可遍历对象转换为真正的数组

    <script type="text/javascript">
        // 扩展运算符可以将数组拆分成以逗号分隔的参数序列
        let ary = ["a", "b", "c"];
        // ...ary // "a", "b", "c"
        console.log(...ary) // 等于console.log("a", "b", "c")


        // 扩展运算符应用于  数组合并  方法一
        let ary1 = [1, 2, 3];
        let ary2 = [4, 5, 6];
        // ...ary1 // 1, 2, 3
        // ...ary1 // 4, 5, 6
        let ary3 = [...ary1, ...ary2];
        console.log(ary3)
        
        //               合并数组   方法二
        let ary1 = [1, 2, 3];
        let ary2 = [4, 5, 6];
        ary1.push(...ary2);
        console.log(ary1)

        // 利用扩展运算符将伪数组转换为真正的数组
        var oDivs = document.getElementsByTagName('div');
        console.log(oDivs)
        var ary = [...oDivs];
        ary.push('a');
        console.log(ary);
    </script>

5.2 构造函数方法:Array.from()

将类数组或可遍历对象转换为真正的数组。

方法还可以接受第二个参数,作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。

    <script type="text/javascript">
         var arrayLike = {
         	"0": "张三",
         	"1": "李四",
         	"2": "王五",
         	"length": 3
         }
         var ary = Array.from(arrayLike);
         console.log(ary)     // 把这个对象的值变成一个数组  

        var arrayLike = {
            "0": "1",
            "1": "2",
            "length": 2
        }
        var ary = Array.from(arrayLike, item => item * 2); 
        // 类似map方法,处理了里面的值, 
        console.log(ary); // 返回的是处理后的值    2 4 4
    </script>

5.2 实例方法:find()

用于找出第一个符合条件的数组成员,如果没有找到返回undefined

    <script type="text/javascript">
        var ary = [{
            id: 1,
            name: '张三'
        }, {
            id: 2,
            name: '李四'
        }];
        let target = ary.find(item => item.id == 2); // 如果是 == 3 则为空
        console.log(target)  // 返回的是 那个属性所在的 对象。
    </script>

5.3 实例方法:findIndex()

用于找出第一个符合条件的数组成员的位置,如果没有找到返回 -1

    <script type="text/javascript">
        let ary = [10, 20, 50];
        let index = ary.findIndex(item => item > 15);
        console.log(index) //  1  返回的是 序号
    </script>

5.4 实例方法:includes()

表示某个数组是否包含给定的值,返回布尔值。

	<script type="text/javascript">
		let ary = ["a", "b", "c"];

		let result = ary.includes('a')
		console.log(result)     // true
		result = ary.includes('e')
		console.log(result)     // false
	</script>

5.0 String 的扩展方法

**5.1 模板字符串 **

ES6新增的创建字符串的方式,使用反引号定义。

		let name = `zhangsan`;
		// 字符串拼接   ${属性名}
        let name = `张三`;
        let sayHello = `Hello, 我的名字叫${name}`; 
        console.log(sayHello);
		
		// 字符串换行   直接用 html 的格式写就可了
        let result = { 
            name: "zhangsan",
            age: 20
        };
        let html = `
			<div>
				<span>${result.name}</span>    
				<span>${result.age}</span>
			</div>
		`;
        console.log(html);
        
		// 模板字符串可以调用函数,函数的调用直接写里面 ${fn()} 
        const fn = () => {  
            return '我是fn函数'
        }
        let html = `我是模板字符串 ${fn()}`;
        console.log(html)

**5.2 实例方法:startsWith() 和 endsWith() **

**startsWith():**表示参数字符串是否在原字符串的头部,返回布尔值

**endsWith():**表示参数字符串是否在原字符串的尾部,返回布尔值

    <script type="text/javascript">
        let str = 'Hello ECMAScript 2015';
        
        // 判断参数字符串是否在源字符串的 头部 ,返回布尔值
        let r1 = str.startsWith('Hello'); 
        console.log(r1); // true
        
        // 判断参数字符串是否在源字符串的 尾部 ,返回布尔值
        let r2 = str.endsWith('2016'); 
        console.log(r2) // true
    </script>

**5.3 实例方法:repeat() **

repeat方法表示将原字符串重复n次,返回一个新字符串。

		'x'.repeat(3) // "xxx" 
		'hello'.repeat(2) // "hellohello"

**6.0 Set 数据结构 **

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

		Set本身是一个构造函数,用来生成 Set 数据结构。
		
		const s = new Set();
		Set函数可以接受一个数组作为参数,用来初始化。
		
		const set = new Set([1, 2, 3, 4, 4]);
		const s = new Set();
		
		 // 向 set 结构中添加值
		s.add(1).add(2).add(3);  
		
		// 删除 set 结构中的2值 s.has(1) // 表示 set 结构中是否有1这个值 返回布尔值
		s.delete(2) 
		
		// 清除 set 结构中的所有值
		s.clear() 

		// 遍历  Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值
		s.forEach(value => console.log(value))
		案例-------------
    <script type="text/javascript">
        const s1 = new Set();
        console.log(s1.size)  //.size 表示这个数据结构里面有几个值 这个是 0 个

        const s2 = new Set(["a", "b"]);
        console.log(s2.size)   //.size 表示这个数据结构里面有几个值 这个是 2 个

        const s3 = new Set(["a", "a", "b", "b"]);
        console.log(s3.size) //.size 这个会过滤重复属性 所以这个只有 2 个
        const ary = [...s3];
        console.log(ary) //这里也只有a, b两个, 这个是利用 size 来去重的方法

        const s4 = new Set();
        // 向set结构中添加值 使用add方法
        s4.add('a').add('b');
        console.log(s4.size)

        // 从set结构中删除值 用到的方法是delete
        const r1 = s4.delete('c');
        console.log(s4.size)
        console.log(r1);
        // 如果没有 c 则返回 false 删除失败

        // 判断某一个值是否是set数据结构中的成员 使用has
        const r2 = s4.has('d');
        console.log(r2) // 里面没有 d 所以返回 false

        // 清空set数据结构中的值 使用clear方法
        s4.clear();
        console.log(s4.size);

        // 遍历set数据结构 从中取值
        const s5 = new Set(['a', 'b', 'c']);
        s5.forEach(value => {
            console.log(value)
        })
    </script>
上一篇:访问者模式(Visitor)及代码实现


下一篇:第一节:访问者模式——需求说明&基本介绍