🌈ES6基础入门 ⭕let和const
let:代替var,用于声明变量的关键字
const:用于声明常量的关键字
💡let、const与var的区别 1. 重复声明:
var允许重复声明,但let和const不允许
2.变量提升:
var存在变量提升,但let和const不存在变量提升(会报错)
3.暂时性死区:
只要作用域内存在let、const,它们声明的变量或常量就自动“绑定“这个区域,不再受到外部作用域的影响,即let和const存在暂时性死区
4.window对象的属性和方法:
全局作用域中,var声明的变量会成为window对象的属性,function声明的函数会成为window对象的方法,而let和const不会
5.块级作用域:
let、const有块级作用域,并且会根据作用域链从内往外被访问到,而var没有块级作用域
⭕模版字符串与箭头函数 💡模板字符串
const str = ‘abc’; // 普通字符串
const str = `abc`; // 模板字符串
实际应用中:
const name = ‘小明’;
const age = 19;
document.body.innerHTML =`我的名字是${name},今年${age}岁了`
❗模板字符串的注意事项
1.输出多行字符串
使用 \n 实现换行:console.log(`第一行\n第二行`)
2.输出`和\等字符
使用\进行转义:console.log(`\``); // `
3.模板字符串的注入
只要最终可以得出一个值的就可以通过${}注入到模板字符串中
⭕箭头函数 💡认识箭头函数
语法:const 函数名 = 参数 => 函数体
将一般函数改写为箭头函数:
const fun = function () {} —改写—> const fun = () => {}
❗箭头函数的注意事项
**1.单个参数体 **——括号可省略
2.单行函数体 ——函数体是单行return语句,可以省略花括号
3.单行对象 ——如果返回单行对象,可以在{}外面加上(),让浏览器不再认为那是函数体的花括号
💡this指向 📍全局作用域中的this指向
📍一般函数(非箭头函数)中的this指向 1 2 3 4 5 6 7 8 9 'use strict' function fun ( ) { console .log (this ); }; fun (); window .fun ();
📍箭头函数中的this指向 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 const fun = ( ) => { console .log (this ); }; const obj = { add : () => { console .log (this ); } }; obj.add (); const cale = { add : function ( ) { const fun = ( ) => { console .log (this ) }; fun (); } } cale.add (); const caleFn = cale.add ;caleFn ();
💡不适用箭头函数的场景 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const Person = ( ) => {};new Person (); document .addEventListener ('click' ,function ( ){ console .log (this ); }); document .addEventListener ('click' ,() => { console .log (this ); }); function fun ( ) { console .log (arguments ); }; fun (1 ,2 ,3 ,4 ); const fun1 = ( ) => { console .log (arguments ); } fun1 (1 ,2 ,3 ,4 );
⭕数组的解构赋值
含义:解析某一数据的结构,将需要的提取出来,赋值给变量或者常量
原理:模式(结构)匹配;索引值相同的完成赋值
💡数组解构赋值的默认值
默认值的基本用法:const [a,b,c] = [1,2,3]
默认值的生效条件:只有当一个数组成员严格等于(===) undefined时,对应的默认值才会生效
默认值表达式:如果默认值是表达式,默认值表达式是惰性求值的
💡数组解构赋值的应用 📍1.常见的类数组的解构赋值
arguments和NodeList
📍2.函数参数的解构赋值 1 2 3 4 const arr = [1 ,2 ];const add = ([x,y] ) => x + y;cosole.log (add (arr));
📍3.交换变量的值 1 2 3 4 5 6 7 8 9 10 11 12 let x = 1 ;let y = 2 ;let temp = x;x = y; y = temp; console .log (x,y);const [y,x] = [x,y];console .log (x,y);
⭕对象的解构赋值 💡对象解构赋值的原理
1.模式(结构)匹配: {} = {}
2.属性名相同的完成赋值:
简写:const {username, age} = {username: ‘小明’, age: 18};
完整的:const {‘username’: username, ‘age’:age} = {username: ‘小明’, age: 18};
取别名: const {username: uname, age} = {username: ‘小明’, age: 18}; // 变量后 ‘ : ‘ 别名
💡对象结构赋值的注意事项
1.默认值的生效条件
对象的属性严格等于(===) undefined时,对应的默认值才会生效
2.默认值表达式
如果默认值是表达式,默认值表达式是惰性求值的
3.将一个已经声明的变量用于解构赋值
如果将一个已经声明的变量用于解构赋值,整个赋值需要再圆括号中进行
let x = 1;
({x}) = {x:2};
4.可以取到继承的属性
const {toString} = {};
console.log(toString); // 可以取到这个方法,因为toString方法是Object身上的
💡对象解构赋值的应用 📍1.函数参数的解构赋值 1 2 3 4 5 6 const fun = user => console .log (user.username , user.age );fun ({username : '李四' , age : 19 });const fun = ({age = 15 , username = '张三' } ) => console .log (username, age);fun ({username : '李四' , age : 19 });
📍2.复杂的嵌套 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const obj = { x :1 , y : [2 ,3 ,4 ], z : { a : 5 , b : 6 } }; const { y, y : [,yy], z, z : { b } } = obj; console .log (yy,y,z,b);
⭕其他数据类型的解构赋值 💡字符串的解构赋值 1 2 3 4 5 6 7 8 const [a,,,b,c] = 'hello' ;console .log (a,b,c);const {0 :a,1 :b,length} = 'hello' ;console .log (a,b,length);]
💡数值和布尔值的解构赋值
会先将数值或者布尔值转换为对象,然后在进行解构赋值(转换为对象后,什么内容都没有!)
💡undefined 和 null 的解构赋值
由于undefined 和 null 没有对应的包装对象,所以无法通过它们转换成相应的对象,所以对他们进行解构赋值,都会报错
⭕对象字面量的增强 📍属性的简洁表示法
当键名和变量或者常量名一样的时候,可以只写一个
1 2 3 4 5 6 const age = 18 ;const person = { age };
📍方法的简洁表示法
方法可以省略冒号和function关键字
1 2 3 4 5 const person = { speak ( ){console .log ('hello' );} };
💡函数参数的默认值 📍认识函数参数的默认值:调用函数的时候传参了,就用传递的参数;如果没传参,就用默认值
📍函数参数默认值的基本用法
1 const fun (x = 1 , y = 2 ) => x * y;
💡函数参数默认值的注意事项 📍默认值的生效条件:不传参数,或者明确的传递undefined作为参数,只有这两种情况,默认值才生效
📍默认值表达式:如果默认值是表达式,默认值表达式是惰性求值的
📍设置默认值的小技巧:函数参数的默认值,最好从参数列表的右边开始设置
💡函数参数默认值的应用
接收很多参数的时候
1 2 const fun = (username = '张三' , age = 18 , gender = '男' ) => console .log (username, age, gender);fun ('李四' , 22 , '女' );
接收一个对象作为参数
1 2 3 4 5 6 const fun = ({username = '张三' , age = 18 , gender = '男' } = {} ) => console .log (username, age, gender);fun ({username : '李四' , age : 22 , gender : '女' });fun ();
⭕剩余参数
含义:当函数接收参数的个数不确定时,可以使用剩余参数
形式:const fun = (x, y, …args) => {}
本质: 剩余参数永远都是一个数组,即使没有值,也是空数组
💡剩余参数的注意事项
1.箭头函数的剩余参数
箭头函数的参数部分即使只有一个剩余参数,也不能省略圆括号
2.使用剩余参数替代arguments获取实际参数
const fun = (…args) => {console.log(args);};
3.剩余参数的位置
剩余参数只能是最后一个参数,之后不能再有其他参数,否则会报错
💡剩余参数的应用 📍1.完成add函数 1 2 3 4 5 6 7 8 9 10 11 12 const add = (...args ) => args.reduce ((prev, next ) => prev + next);console .log (add (1 , 2 , 3 ));
📍2.与解构赋值结合使用 1 2 3 4 5 6 7 8 const [a,...args] = [1 ,2 ,3 ,4 ];console .log (a,args); const {x,y,...z} = {a : 3 , x : 1 , y : 2 , b : 4 }; console .log (x, y, z);
⭕数组展开运算符
基本用法:
例如找到数组中的最小值,可以使用Math.min(),但其参数是数字列表,可以使用展开运算符实现将数组展开为数字列表
consolo.log(Math.min(…[4, 2, 3])); 相当于 console.log(Math.min(4, 2, 3))
💡区分剩余参数和展开运算符
根本区别:
展开运算符:[1, 2, 3] —> 1, 2, 3
剩余参数:1, 2, 3 —> [1, 2, 3]
⭕对象展开运算符
1,展开对象
对象不能直接展开,必须在{}中展开
对象的展开:把属性罗列出来,用逗号分隔,放到一个{}中,构成新对象
2.合并对象
const obj1 = {……} , const obj2 = {……}
console.log({…obj1, …obj2});
新对象拥有全部属性,相同属性,后者覆盖前者
💡对象展开运算符的注意事项
1.空对象的展开
如果展开一个空对象,则没有任何效果
2.非对象的展开
如果展开的不是对象,则会自动将其转为对象,再将其属性罗列出来
如果展开运算符后面是字符串,他会自动转成一个类似数组的对象,因此返回的不是空对象
3.对象中对象属性的展开
不会展开对象中的对象属性
💡对象展开运算符的应用 📍1.复制对象 1 2 3 4 5 6 7 8 9 const obj1 = { name : '张三' , age : 18 , gender : '男' , }; const obj2 = { ...obj1 };console .log (obj2); console .log (obj2 === obj1);
📍用户参数和默认参数 1 2 3 4 5 6 7 8 9 10 11 12 const loUser = userParam => { const defaultParam = { username : 'zhangsan' , age : 19 , gender : '男' , }; const { username, age, gender } = { ...defaultParam, ...userParam }; console .log (age, username, gender); };
⭕Set 和 Map 数据结构 💡认识Set
含义:Set是一系列无序、没有重复值的数据集合,即Set中不能有重复的成员,Set没有下标去标识每一个成员
💡Set实例的方法和属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 const s = new Set ();s.add (1 ).add (2 ).add (2 ); console .log (s); console .log (s.has (1 )); console .log (s.has (3 )); s.forEach (function (value, key, set ) { console .log (this ); },document ); console .log (s.size );
💡Set构造函数的参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const s = new Set ([1 , 2 , 3 , 1 ]);console .log (new Set (s)); console .log (new Set (s) === s);
💡Set 的注意事项 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const s = new Set ();s.add ({}).add ({}); console .log ({} === {}); console .log (s);
💡Set 的应用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const s = new Set (document .querySelectorAll ('p' ))s.forEach (elem => { elem.style .color = 'red' elem.style .backgroundColor = 'yellow' })
💡认识Map
含义:键值对的集合,可以称作映射
形式:键 -> 值,key -> value
❗Map和对象的区别 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 const obj = { name : 'zhangsan' , age : 19 , [{}]: 'object' , }; console .log (obj);console .log ({}.toString ());const m = new Map ();m.set ('name' , 'lisi' ); m.set ('age' , 18 ); m.set (true , 'true' ); m.set (undefined , 'undefined' ); m.set (null , 'null' ); m.set ({},'object' ) m.set ([],'array' ) m.set ((x,y )=> x+y,'function' ) m.set (new Set ([1 ,2 ,3 ]),'set' ) m.set (new Map (),'map' ) console .log (m);
💡Map实例的方法和属性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 const m = new Map ();m.set ('name' , 'zhangsan' ).set ('age' , 19 ).set ('gender' , '男' ); console .log (m);console .log (m.get ('age' ));console .log (m.has ('gender' ));m.forEach (function (value,key,map ) { console .log (value,key,map) console .log (this ) },document ) console .log (m.size )
💡Map构造函数的参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 const m = new Map ([ ['name' , 'zhangsan' ], ['age' , 19 ], ['gender' , 'male' ], ]); console .log (new Map (m) === m); console .log (new Map (m));
💡Map的注意事项 1 2 3 4 5 6 7 8 9 const m = new Map ();m.set (NaN ,1 ).set (NaN ,2 ); console .log (m);
💡Map的应用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 const [p1, p2, p3] = document .querySelectorAll ('p' );const m = new Map ([ [ p1, { color : 'red' , backgroundColor : 'yellow' , fontSize : '30px' , }, ], [ p2, { color : 'yellow' , backgroundColor : 'pink' , fontSize : '16px' , }, ], [ p3, { color : 'pink' , backgroundColor : 'blue' , fontSize : '23px' , }, ], ]); m.forEach ((elemStyle, elem ) => { console .log (elemStyle) for (const propStyle in elemStyle) { elem.style [propStyle] = elemStyle[propStyle]; } });
⭕遍历器与for…of循环 💡认识Iterator
作用:Iterator称为遍历器(迭代器),用于遍历的一种方式
寻找Iterator:console.log( [1,2][Symbol.Iterator]() ); // Array Iterator {}
📍使用Iterator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // 找到Iterator // const it = [1, 2][Symbol.iterator](); // console.log(it); // Array Iterator {} // 使用Iterator const it = [1, 2][Symbol.iterator](); console.log(it.next()); // {value: 1, done: false} console.log(it.next()); // {value: 2, done: false} console.log(it.next()); // {value: undefined, done: true} console.log(it.next()); // {value: undefined, done: true} // it: 可遍历对象(可迭代对象) // Symbol.iterator: 可遍历对象的生成方法 // 什么是Iterator // Symbol.iterator(可遍历对象的生成方法)--> it(可遍历对象)--> it.next() --> it.next() --> ...(直到done 为 true)
💡Iterator疑惑
1.为什么需要Iterator 遍历器
遍历数组:for 循环 和 forEach 方法
遍历对象:for…in 循环
Iterator 遍历器是一个统一的遍历方式
2.如何更方便的使用Iterator
一般不会直接使用Iterator去遍历,已经封装好了一套 —— for…of 循环
💡认识for…of 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 const arr = [1 , 2 , 3 ];for (const item of arr) { console .log (item); }
💡for…of的用法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const arr = [1 , 2 , 3 ];for (const index of arr.keys ()) { } for (const value of arr.values ()) { } for (const [key,value] of arr.entries ()) { console .log (key,value); }
💡原生可遍历和非原生可遍历
1.什么是可遍历
只要有 Symbol.iterator() 方法,并且这个方法可以生成可遍历对象,就是可遍历的
只要是可遍历对象,就可以使用for…of 循环来统一遍历
2.原生可遍历有哪些
①数组 ②字符串 ③Set ④Map ⑤arguments ⑥NodeList
3.非原生可遍历有哪些
①一般的对象 —— 直接使用 for…in 遍历即可(不建议手搓Symbol.iterator方法)
⭕ES6新增方法 💡字符串的新增方法 🐼includes() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 console .log ('abc' .includes ('a' )); console .log ('abc' .includes ('ab' )); console .log ('abc' .includes ('bc' )); console .log ('abc' .includes ('ac' )); console .log ('abc' .includes ('a' , 0 )); console .log ('abc' .includes ('a' , 1 )); let url = 'https://yubai.eu.org?' ;const urlConcat = (url, key, value ) => { if (url[url.length -1 ] === '?' ){ url += `${key} =${value} ` ; return url } else { url += url.includes ('?' )? '&' : '?' ; url += `${key} =${value} ` ; return url; } }; url = urlConcat (url, 'name' , 'admin' ); url = urlConcat (url, 'password' , '123456' ); console .log (url);
🐼padStart() 和 padEnd() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 console .log ('x' .padStart (5 , 'ab' )); console .log ('x' .padEnd (5 , 'ab' )); console .log ('x' .padEnd (4 , 'ab' )); console .log ('xxx' .padStart (2 , 'ab' )); console .log ('xxx' .padEnd (2 , 'ab' )); console .log ('xxx' .padStart (10 , '0123456789' )); console .log ('xxx' .padEnd (10 , '0123456789' )); console .log ('x' .padStart (4 )); console .log ('x' .padEnd (4 )); const date = new Date ();const year = date.getFullYear ()const Month = date.getMonth () + 1 const day = date.getDate ()console .log (`今天的日期:${year} -${Month.toString().padStart(2 ,'0' )} -${day.toString().padStart(2 ,'0' )} ` );
🐼trimStart() 和 trimEnd() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" /> <meta name ="viewport" content ="width=device-width, initial-scale=1.0" /> <title > Document</title > </head > <body > <input type ="text" name ="" id ="content" > <input type ="submit" value ="提交" id ="btn" > <script > const str = ' a b c ' ; console .log (str.trimStart ()); console .log (str.trimEnd ()); console .log (str.trimLeft ()); console .log (str.trimRight ()); console .log (str.trim ()); const content = document .getElementById ('content' ) const btn = document .getElementById ('btn' ) btn.addEventListener ('click' ,()=> { if (!content.value .trim ()) return alert ('提交不通过' ) alert ('提交通过' ) }) </script > </body > </html >
💡数组的新增方法 🐼includes() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 console .log ([1 , 2 , 3 ].includes ('2' )); console .log ([1 , 2 , 3 ].includes (2 )); console .log ([1 , 2 , 3 ].includes (2 , 2 )); const arr = [1 , 2 , 1 ];const result = [];for (const item of arr) { if (!result.includes (item)) { result.push (item); } } console .log (result);
🐼Array.from() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 console .log (Array .from ('str' )); console .log (Array .from (new Set ([1 , 2 , 1 ]))); console .log ([...new Set ([1 , 2 , 1 ])]); const obj = { 0 : 'a' , 1 : 'b' , name : 'Lisa' , length : 3 , }; console .log (Array .from (obj));console .log ( [1 , 2 ].map (value => { return value * 2 ; }) ); console .log (Array .from ([1 , 2 ], value => value * 2 )); console .log ([1 , 2 ].map (value => value * 2 )); console .log ( Array .from ( [1 , 2 ], function ( ) { console .log (this ); }, document ) );
🐼find() 和 findIndex() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 console .log ( [1 , 5 , 16 , 23 ].find ((value, index, arr ) => { return value > 9 ; }) ); console .log ( [1 , 5 , 16 , 23 ].findIndex ((value, index, arr ) => { return value > 9 ; }) ); console .log ( [1 , 5 , 16 , 23 ].find (function (value, index, arr ) { console .log (this ); }, document ) ); const students = [ { name : '张三' , age : 18 , gender : '男' , }, { name : '李四' , age : 12 , gender : '男' , }, { name : '小美' , age : 22 , gender : '女' , }, ]; console .log (students.find ((value, index ) => value.gender == '女' ));console .log (students.findIndex ((value, index ) => value.gender == '女' ));
💡对象的新增方法 🐼Object.assign() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 console .log (Object .assign ({}, undefined )); console .log (Object .assign ({}, null )); console .log (Object .assign ({}, 123 )); console .log (Object .assign ({}, true )); console .log (Object .assign ({}, 'string' )); const apple = { color : ['红色' , '黄色' ], shape : '圆形' , taste : '甜' , }; const pen = { color : ['黑色' , '蓝色' ], shape : '圆柱体' , use : '写字' , }; console .log (Object .assign (apple, pen)); const logUser = userOptions => { const DEFAULTS = { username : 'zhangsan' , age : 18 , gender : 'male' , }; return Object .assign ({}, DEFAULTS , userOptions); }; console .log (logUser ({ username : '李华' , age : 25 }));
🐼Object.keys() 、Object.values() 、Object.entries() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 const student = { name : 'zhangsan' , age : 19 , gender : 'male' , }; console .log (Object .keys (student)); console .log (Object .values (student)); console .log (Object .entries (student)); console .log ([1 , 2 ].keys ()); console .log ([1 , 2 ].values ()); console .log ([1 , 2 ].entries ()); const person = { name : 'zhangsan' , age : 18 , gender : 'male' , }; for (const value of Object .values (person)) { console .log (value); } for (const key of Object .keys (person)) { console .log (key); } for (const [key, value] of Object .entries (person)) { console .log (key, value); }