二、ES6新语法

    技术2022-07-11  90

    let关键字

    特点var关键字let关键字变量提升√×作用域没有块级作用域,是函数作用域有块级作用域重复声明√×重新赋值√√

    变量提升

    console.log(age); let age = 38;

    作用域

    for (var i = 0; i < 10; i++) {} console.log(i); for (let n = 0; i < 10; i++) {} console.log(n);

    图中可对比看出,如果用var声明,在循环外部还是可以使用i变量;但用let声明变量,循环外部不可以使用n变量

    不可重复声明

    let num2 = 10; let num2 = 20; console.log("num2: ", num2);

    重新赋值

    let num2 = 10; num2 = 20; console.log("num2: ", num2);

    const关键字

    使用场景

    一些不会变化的值,比如圆周率PI大事件项目中,保存基地址

    没有变量提升

    有块级作用域

    不能重复声明

    不能重新赋值(声明必须要初始化)

    解构赋值

    对象解构

    取对象中属性的值,赋值给变量。

    例如对于如下对象来说,在ES5与ES6中将对象赋值于变量的方式

    let obj = { name: "波波", age: 38, gender: "男", score: 88, };

    ES5中的写法

    let name1 = obj.name; let age1 = obj.age; let gender1 = obj.gender; let score1 = obj.score; console.log(name1, age1, gender1, score1);

    ES6中的写法

    定义变量名

    let { name: name2, age: age2, gender: gender2, score: score2 } = obj; console.log(name2, age2, gender2, score2);

    变量名可与属性名一致

    let { name: name, age: age, gender: gender, score: score } = obj; console.log(name, age, gender, score);

    当变量名与属性名一致时,可以省略变量名

    let { name, age, gender, score } = obj; console.log(name, age, gender, score);

    以上代码的输出结果都为下图所示

    当简写时,对象中没有的属性会赋值为undefined

    let obj = { name: "波波", age: 38, gender: "男", score: 88, }; let { name, age, gender, fenshu } = obj; console.log(name, age, gender, fenshu);

    简写与全写可以一起用

    let { name, age, gender, score: fenshu } = obj; console.log(name, age, gender, fenshu);

    设置默认值。当对象中没有此属性时会赋值为默认值而不是undefined。如果对象中存在这个属性,那么将赋值为对象中的属性,而不是默认值。

    let { name, age, gender, score: fenshu, height = 180 } = obj; console.log(name, age, gender, fenshu, height);

    赋值一个除了某个属性不存在,但存在其余属性的对象

    let obj = { name: "波波", age: 38, gender: "男", score: 100, }; // obj2相当于是obj对象里面除了name属性之外的属性组成的一个对象 let { name, ...obj2 } = obj; console.log(obj2); // { age: 38, gender: '男', score: 100 }

    数组解构

    把数组中每一个元素的值依次的赋值给变量。声明如下数组:

    // 声明一个数组 let arr = [10, 20, 30, 40];

    ES5中的写法

    let num1 = arr[0]; let num2 = arr[1]; let num3 = arr[2]; let num4 = arr[3]; console.log(num1, num2, num3, num4);

    ES6中的写法

    基础写法–一一对应

    let [num1, num2, num3, num4] = arr; console.log(num1, num2, num3, num4);

    默认值与没有值时与对象解构一致。

    let [num1, num2, num3, num4, num5] = arr; console.log(num1, num2, num3, num4, num5); // num5为undefined let [num1, num2, num3, num4, num5=5] = arr; console.log(num1, num2, num3, num4, num5); // num5为5

    解构赋值结合函数声明

    ES5中的写法

    function test1(obj) { console.log(obj.name, obj.age, obj.gender); } test1({ name: "波波", age: 38, gender: "男", });

    ES6中的写法

    function test2({ name, age, gender, height = 180 }) { console.log(name, age, gender, height); } test2({ name: "波波", age: 38, gender: "男", }); test2({ name: "波波", age: 38, gender: "男", height: 160, });

    箭头函数

    简单来说,箭头函数就是匿名函数的一个简写。

    // 1. 普通的匿名函数 let fn = function (name) { console.log("my name is ", name); }; fn("波波"); // 2. 箭头函数 let fn1 = (name) => console.log("my name is ", name); fn1("波波");

    简写规则:

    function改成=>,=>可以读成goes to

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

    如果不是一个形参(0个或多个),那就不能省略形参小括号

    如果函数体只有一句话,那就可以省略函数体的大括号

    如果函数体只有一句话,并且这一句话是return返回值,那return也要省略

    let fn1 = function (name) { return name + "你好吗?"; }; let fn1 = (name) => name + "你好吗?";

    如果函数体不是一句话,那就不能省略这个大括号

    let fn2 = function (num1, num2) { console.log(num1 + num2); return num1 + num2 + 30; }; let fn2 = (num1, num2) => { console.log(num1 + num2); return num1 + num2 + 30; };

    无参数,一句话

    let fn1 = function () { console.log("你好吗"); }; let f1 = () => console.log("你好吗");

    一个参数,一句话

    let fn2 = function (name) { console.log(name + "你好吗"); }; let fn2 = (name) => console.log(name + "你好吗");

    两个参数,一句话

    let fn3 = function (name, age) { console.log(name + "你好吗,你的年龄是" + age); }; let fn3 = (name, age) => console.log(name + "你好吗,你的年龄是" + age);

    一个参数,一个return

    let fn4 = function (age) { return age + 10; }; let fn4 = (age) => age + 10;

    两个参数,多句

    let fn5 = function (name, age) { console.log(name + "你好吗"); return age + 10; }; let fn5 = (name, age) => { console.log(name + "你好吗"); return age + 10; };

    this指向

    箭头函数的this由上下文环境决定,其原理就是将箭头函数的上下文this保存,在箭头函数内部使用这个被保存的this。使用注意:

    不是什么时候都使用箭头函数

    不要用new关键字调用箭头函数

    var Fn = (name, age) => { this.name = name this.age = age } var obj = new Fn('伦哥', 10) // Fn is not a constructor

    箭头函数的this是由上下文环境决定,而不是new关键字来决定

    var obj = { name: '波波', sayHi: function () { console.log('我的名字是:', this.name) // 我的名字是: 波波 // 上文环境 setTimeout(() => { console.log('我的名字是:', this.name) // 我的名字是: 波波 }, 2000) // 下文环境 } } obj.sayHi()

    当多层箭头函数套用时,那么里面的this指向都与最外层的this指向一致。

    var obj = { name: '波波', sayHi: function () { console.log('我的名字是1:', this.name) // 上文环境 setTimeout(() => { console.log('我的名字是2:', this.name) setTimeout(() => { console.log('我的名字是3:', this.name) setTimeout(() => { console.log('我的名字是4:', this.name) }, 1000) }, 1000) }, 1000) // 下文环境 } } obj.sayHi()

    对象成员简写

    let name = "千里"; let age = 18; let gender = "man"; let score = 10; // es6 let obj = { name, age, gender, score, sayHi() { console.log("哈哈"); }, }; console.log(obj); obj.sayHi();

    在这种写法中,如果传入一个没有赋值的变量,那么就会报错。例如:

    let name = "千里"; let age = 18; let gender = "man"; let score = 10; // es6 let obj = { name, age, gender, score, // fenshu, // 会发生报错,因为外部没有此变量,可以修改为下面的写法 fenshu:score, sayHi() { console.log("哈哈"); }, }; console.log(obj); obj.sayHi();

    扩展(展开)运算符

    对象展开

    // 声明一个对象 let chinese = { skin: "yellow", hair: "black", sayHi() { console.log("Are you eat?"); }, }; let CXK = { slill: "jump sing rap and play basketball", song: "啊哈哈哈", }; let linge = { // skin: "yellow", // hair: "black", // sayHi() { // console.log("Are you eat?"); // }, // slill: "jump sing rap and play basketball", // song: "啊哈哈哈", // 展开语法 等同于上方写法 ...chinese, ...CXK, }; console.log(linge);

    当新增属性时,直接添加即可。如果重新定义已经存在的,那么覆盖原来的。

    let linge = { ...chinese, ...CXK, gender: "Man", hair: "白发苍苍", };

    数组展开

    与对象展开类似。

    let arr1 = [10, 20, 30]; let arr2 = [40, 50, 60]; let arr3 = [...arr1, ...arr2, 70]; console.log(arr3);

    使用场景:

    数组的拼接

    求最大/小值

    let arr1 = [10, 23, 54, 446, 56, 2]; let max = Math.max(...arr1); console.log(max);

    数据类型set

    作用和数组类型,和数组不同的是set不能存放重复的元素。

    基本使用

    let set1 = new Set([10, 20, 30, 40, 10, 20, 30, 40, 50]); console.log(set1);

    数组去重

    let arr = [10, 20, 30, 10, 20, 30, 20, 10, 33, 200]; let set = new Set(arr); let arrNew = [...set]; console.log(arrNew);

    也可以改写为如下:

    let arr = [10, 20, 30, 10, 20, 30, 20, 10, 33, 200]; let arrNew = [...new Set(arr)]; console.log(arrNew);

    模板字符串

    模板字符串会保留原样字符串格式,以及可以占位。其语法为反引号``

    let author = "波波"; let str1 = ` 静夜思 ${author} 哈哈哈 `; console.log(str1);

    let name = "xiaokang"; let age = 12; function test() { return "test"; } console.log(`my name is ${name} and age is ${age}. ${test()}`);

    补充数组的方法

    forEach

    无返回值

    let arr = [10, 20, 30, 40]; arr.forEach(function (item, index) { // item 遍历出的每一项 // index 遍历出来的每一项对应的索引 console.log(item, index); });

    map

    有返回值。

    let arr = [10, 20, 30, 40]; let arrNew = arr.map(function (item, index) { // item 遍历出的每一项 // index 遍历出来的每一项对应的索引 // console.log(item, index); return item * item; }); console.log(arrNew);

    filter

    let arr = [10, 20, 11, 21, 30, 31, 23, 43]; let arrNew = arr.filter((item, index) => { console.log(item, index); // 如果条件成立,返回当前项 return item % 2 == 0; }); console.log(arrNew); //[ 10, 20, 30 ]

    数组的其他应用

    数组降维

    将二维数组降维为一维数组

    // 将二维数组将为一维数组 var arr = [[10, 20], [30, 40, 50], [60, 79, 80]] var arrNew = [] arr.forEach(v => { arrNew.push(...v) }) console.log(arrNew); // [10, 20, 30, 40, 50, 60, 79, 80]

    数组的去重(排序法)

    var arr = [10, 20, 30, 23, 4, 512, 20, 10]; var arrNew = []; arr.sort((a, b) => { return a - b; }); console.log(arr); // [4, 10, 10, 20, 20, 23, 30, 512]; arr.forEach((v, i) => { if (v != arr[i + 1]) { arrNew.push(v); } }); console.log(arrNew); // [ 4, 10, 20, 23, 30, 512 ]

    数组去重(对象法)

    原理:利用对象属性不能同名。

    // 使用对象法 var obj = {}; var arrNew = []; // 遍历要去重的数组 arrNew.forEach((v) => { if (obj[v] == undefined) { arrNew.push(v); // 不存在九江这个v存起来 obj[v] = 1; // 随意写,作为属性的值(避免undefined) } });

    数组升维

    假设从后端拿到的数据为如下格式:

    var arr = [ { type: "电子产品", name: "iPhone", price: 8888 }, { type: "家具", name: "桌子", price: 100 }, { type: "食品", name: "瓜子", price: 10 }, { type: "家具", name: "椅子", price: 380 }, { type: "电子产品", name: "小米手机", price: 1380 }, { type: "食品", name: "辣条", price: 5 }, { type: "食品", name: "咖啡", price: 50 }, ];

    第一种:

    var obj = {}; //将测type有没有重复的 var arrNew = []; // 升级后的二维数组 // 1. 将type去重,找出所有的产品类型 // 遍历这个arr一维数组 arr.forEach((v) => { if (obj[v.type] == undefined) { obj[v.type] = 1; // 把这个数组放到arrNew中 arrNew.push({ type: v.type, data: [v], }); } else { // 判断当前v输入arrNew中的哪一类 arrNew.forEach((v2, j) => { if (v.type == v2.type) { arrNew[j].data.push(v); } }); } }); console.log(arrNew);

    第二种:

    var obj = {}; //将测type有没有重复的 var arrNew = []; // 升级后的二维数组 var index = 0; // 用于记录索引 arr.forEach((v) => { if (obj[v.type] == undefined) { obj[v.type] = index++; // 把这个数组放到arrNew中 arrNew.push({ type: v.type, data: [v], }); } else { var _index = obj[v.type]; arrNew[_index].data.push(v); } }); console.log(arrNew);

    babel将ES6代码转为ES5

    https://www.babeljs.cn/

    Processed: 0.009, SQL: 9