变量提升
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);使用场景
一些不会变化的值,比如圆周率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为5ES5中的写法
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。使用注意:
不是什么时候都使用箭头函数
不要用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, // fenshu, // 会发生报错,因为外部没有此变量,可以修改为下面的写法 fenshu:score, sayHi() { console.log("哈哈"); }, }; console.log(obj); obj.sayHi();当新增属性时,直接添加即可。如果重新定义已经存在的,那么覆盖原来的。
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不能存放重复的元素。
基本使用
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);https://www.babeljs.cn/