let
1 2 3 4
| 1. 变量不能重复声明 2. 块级作用域(只在代码块{}里有效) 3. 不存在变量提升 4. 不影响作用域链
|
const
1 2 3 4 5 6
| 1. 一定要赋初始值 2. 一般常量使用大写(潜规则) 3. 不存在变量提升 4. 常量的值不能修改 5. 块级作用域(只在代码块{}里有效) 6. 对于数组和对象内的元素修改,不算做对常量的修改,不会报错
|
let,const 声明的变量不会和window挂钩
globalThis
可以拿到顶层对象
解构赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
1. 数组的结构 const F4 = ['a','b','c','d']; let [e,f,g,h] = F4;
2. 对象的结构 const zhao = { name:'a', age:'b', xiaoping:function(){ console.log('我可以演小品'); } } let {name,age,xiaopin} = zhao let {name:a,age:b,xiaopin:c} = zhao
|
数组解构赋值
1 2
| let [ , , third] = ["foo", "bar", "baz"]; third
|
1 2 3
| let [head, ...tail] = [1, 2, 3, 4]; head tail
|
1 2 3 4 5
| let [x, y, ...z] = ['a']; x y z
|
1 2 3 4 5 6 7 8 9
| let [x, y] = [1, 2, 3]; x y
let [a, [b], d] = [1, [2, 3], 4]; a b d
|
1 2 3
| let [x, y, z] = new Set(['a', 'b', 'c']); x
|
1 2 3 4 5 6
| let [foo = true] = []; foo
let [x, y = 'b'] = ['a']; let [x, y = 'b'] = ['a', undefined];
|
只要某种数据结构具有 Iterator(迭代器) 接口,都可以采用数组形式的解构赋值。
对象解构赋值
1 2 3 4 5 6 7
| let { bar, foo } = { foo: 'aaa', bar: 'bbb' }; foo bar
let { baz } = { foo: 'aaa', bar: 'bbb' }; baz
|
1 2 3 4 5 6 7 8 9 10 11
| let obj = { p: [ 'Hello', { y: 'World' } ] };
let { p: [x, { y }] } = obj; x y
|
1 2 3 4
| let arr = [1, 2, 3]; let {0 : first, [arr.length - 1] : last} = arr; first last
|
字符串的解构赋值
1 2 3 4 5 6
| const [a, b, c, d, e] = 'hello'; a b c d e
|
1 2
| let {length : len} = 'hello'; len
|
数值和布尔值的解构赋值
1 2 3 4 5 6
| let {toString: s} = 123; s === Number.prototype.toString
let {toString: s} = true; s === Boolean.prototype.toString
|
函数参数的解构赋值
1 2 3 4 5
| function add([x, y]){ return x + y; }
add([1, 2]);
|
1 2
| [[1, 2], [3, 4]].map(([a, b]) => a + b);
|
用途
交换变量的值
1 2 3 4
| let x = 1; let y = 2;
[x, y] = [y, x];
|
提取 JSON 数据
解构赋值对提取 JSON 对象中的数据,尤其有用。
1 2 3 4 5 6 7 8 9 10
| let jsonData = { id: 42, status: "OK", data: [867, 5309] };
let { id, status, data: number } = jsonData;
console.log(id, status, number);
|
函数参数的默认值
1 2 3 4 5 6 7 8 9 10 11
| jQuery.ajax = function (url, { async = true, beforeSend = function () {}, cache = true, complete = function () {}, crossDomain = false, global = true, // ... more config } = {}) { };
|
遍历 Map 结构
任何部署了 Iterator 接口的对象,都可以用for...of
循环遍历。Map 结构原生支持 Iterator 接口,配合变量的解构赋值,获取键名和键值就非常方便。
1 2 3 4 5 6 7 8 9
| const map = new Map(); map.set('first', 'hello'); map.set('second', 'world');
for (let [key, value] of map) { console.log(key + " is " + value); }
|
按需导入模块的指定方法
加载模块时,往往需要指定输入哪些方法。解构赋值使得输入语句非常清晰。
1
| const { SourceMapConsumer, SourceNode } = require("source-map");
|
模板字符串
1 2 3
| let str = ``;
let str = `${value}`;
|
对象的简写
1 2 3 4 5 6 7 8 9 10 11 12
| let name = 'a'; let change = function(){ console.log('我们可以改变你!'); }
const school = { name, change, improve(){ console.log('我们可以提高你的技能'); } }
|
箭头函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| let fn = function(a,b){ return a + b; } let fn = (a,b) => { return a + b; } 1. this 是静态的 this 始终指向函数声明时所在作用域下的 this 的值 2. 不能作为构造函数实例化对象 3. 不能使用 arguments 变量 4. 简写 1) 省略小括号, 当形参有且只有一个的时候 let add = n =>{} 2) 省略花括号, 当代码体只有一条语句的时候, 此时return 必须省略 而且语句的执行结果就是函数的返回值 let pow = n => n*n;
|
参数默认值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 1. 形参初始值 具有默认值的参数,一般位置要靠后(潜规则) function add(a,b,c=10){ return a + b + c; }
2. 与解构赋值结合 function connect({host="127.0.0.1",username,password,port}){ console.log(host) console.log(username) console.log(password) console.log(port) } connect({ host:'localhost', username:'root', password:'root', port:3306 })
|
rest参数(剩余参数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function date(...args){ console.log(args); } date('a','b','c');
function fn(a,b,...args){ console.log(a); console.log(b); console.log(args); } fn(1,2,3,4,5,6);
let arr = ['a','b','c']; let [x,...y] = arr;
|
spread扩展运算符
1 2 3 4 5 6 7
| const arr = ['a','b','c']; function fn(){ console.log(arguments); } fn(arr); fn(...arr);
|
扩展运算符应用
1 2 3 4 5 6 7 8 9 10 11 12 13
| const a = ['x','y']; const b = ['z','h']; const ab = [...a,...b]; const a.push(...b);
const a = ['x','y','z']; const b = [...a];
const divs = document.querySelectorAll('div'); const divArr = [...divs];
|
Array的扩展方法
Array.from
1 2 3 4 5 6 7 8
| let arr = Array.from(类数组); 1、该类数组对象必须具有length属性,用于指定数组的长度。如果没有length属性,那么转换后的数组是一个空数组。 2、该类数组对象的属性名必须为数值型或字符串型的数字,如果不是 结果是长度为4,元素均为undefined的数组 ps: 该类数组对象的属性名可以加引号,也可以不加引号
let arr = Array.from(类数组,item => item + 1); Array.from还可以接受第二个参数,用来对每个元素进行处理
|
Array.find()
1 2 3 4 5 6 7
| const array1 = [5, 12, 8, 130, 44];
const found = array1.find(element => element > 10);
console.log(found);
|
Array.findIndex()
1 2 3 4 5 6 7
| const array1 = [5, 12, 8, 130, 44];
const isLargeNumber = (element) => element > 13;
console.log(array1.findIndex(isLargeNumber));
|
Array.includes()
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const array1 = [1, 2, 3];
console.log(array1.includes(2));
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
console.log(pets.includes('at'));
|
String 的扩展方法
startsWith方法和endWith方法
1 2
| str.startsWith(''); str.endsWith('');
|
repeat方法
Set数据结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const s = new Set([1,2,3]); s.size
s.add() s.delete() s.has() s.clear()
s.forEach(item=>{ console.log(item); });
for(let item of s){ console.log(item) }
|
其他(了解)
Object.freeze(obj)
方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。freeze()
返回和传入的参数相同的对象。
Symbol基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 1. Symbol 的值是唯一的,用来解决命名冲突的问题 2. Symbol 值不能与其他数据进行运算 3. Symbol 定义的对象属性不能使用for...in 循环遍历,但是可以使用Reflect.ownKeys来获取对象的所有键名
let s = Symbol(); let s1 = Symbol('a'); let s2 = Symbol('a');
let s3 = Symbol.for('a'); let s4 = Symbol.for('a');
|
Symbol创建对象属性
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
| let game = {}
let methods = { up:Symbol(), down:Symbol() }; game[methods.up] = function(){ console.log('我可以改变形状'); } game[methods.up] = function(){ console.log('我可以快速下降'); }
let youxi = { name:'狼人杀', [Symbol('say')]:function(){ console.log('我可以发言') }; [Symbol('zibao')]:function(){ console.log('我可以自爆') }; }
|
Symbol内置属性
11个(在特定场景下的表现)
迭代器
1 2 3 4 5 6 7 8 9 10
|
1. ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费 2. 原生js具备iterator接口的数据(可用for of遍历) Array Arguments Set Map String TypedArray NodeList
const arr = ['a','b','c','d']; for(let v of arr){ console.log(v); }
|
迭代器自定义遍历对象
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
| const banji = { name:"终极一班", stus:[ '小明', '小红', '小李', '小赵' ], [Symbol.iterator](){ let index = 0; let _this = this; return { next:function(){ if(index < _this.stus.length){ const result = {value:_this.stus[index],done:false}; index++; return result; }else{ return {value:undefined,done:true}; } } }; } }
for(let v of banji){ console.log(v); }
|
生成器函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
function * gen(){ console.log(111); yield '一只没有耳朵'; console.log(222); yield '一只没有眼睛'; console.log(333); yield '真奇怪'; console.log(444); } let iterator = gen(); console.log(iterator.next()); console.log(iterator.next('ccc')); console.log(iterator.next()); console.log(iterator.next());
for(let v of gen()){ console.log(v); }
|
生成器函数实例
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
| function one(){ setTimeout(()=>{ console.log(111); iterator.next(); },1000) }
function two(){ setTimeout(()=>{ console.log(222); iterator.next(); },2000) }
function three(){ setTimeout(()=>{ console.log(333); iterator.next(); },3000) }
function * gen(){ yield one(); yield two(); yield three(); }
let iterator = gen(); iterator.next();
|
实例化Promise对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const p = new Promise(function(resolve,reject){ setTimeout(function(){ let data = '数据库中的用户数据'; resolve(data); let err = '数据读取失败'; reject(err); },1000); })
p.then(function(value){ console.log(value); },function(reason){ console.log(reason); })
|
Promise读取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const p = new Promise(function(resolve,reject){ fs.readFile("./resources/为学.md",(err,data)=>{ if(err) reject(err); resolve(data); }); });
p.then(function(value){ console.log(value.toString()); },function(reason){ console.log("读取失败!!"); });
|
Map
1 2 3 4 5 6 7 8 9
| Map数据结构.类似于对象,也是键值对的集合,但是键的范围不限于字符串 let m = new Map();
m.size m.set('键','值') m.get('键') m.has('') m.delete('键') m.clear()
|
class 类
1 2 3 4 5 6 7 8 9 10 11
| class Phone{ constructor(brand,price){ this.brand = brand; this.price = pricel } call(){ console.log('我可以打电话!') } }
let onePlus = new Phone('1+',1999)
|
static
1 2 3 4 5 6 7 8 9 10 11 12 13
| static 标记的就是静态成员
class Phone { static name = '手机'; static change(){ console.log('我可以改变世界'); } }
let nokia = new Phone(); console.log(nokia.name); console.log(Phone.name);
|
类继承
1 2 3 4 5
| class Son extends Father{ constructor(a,b){ super(a,b); } }
|
get和set
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Phone{ get price(){ console.log('我被读取了'); return 'iloveyou'; } set price(newVal){ console.log('价格属性被修改了'); } }
let s = new Phone(); console.log(s.price); s.price = 'free';
|
数值扩展
1 2 3 4 5 6 7 8
| 0. Number.EPSILON 是JavaScript 表示的最小精度 1. 二进制和八进制 2. Number.isFinite 检测一个数值是否为有限数 3. Number.isNaN 检测一个数值是否为NaN 4. Number.parseInt Number.parseFloat字符串转整数 5. Number.isInteger 判断一个数是否为整数 6. Math.trunc 将数字的小数部分抹掉 7. Math.sign 判断一个数到底为正数 负数 还是零
|
对象方法扩展
1 2 3
| 1. Object.is 判断两个值是否完全相等 2. Object.assign 对象的合并 3. Object.setPrototypeOf 设置原型对象 Object getPrototypeOf
|
模块化
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
| 1. 防止命名冲突 2. 代码复用 3. 高维护性
ES6之前的模块化规范有: 1. CommonJS => NodeJS,Browserify 2. AMD => requireJS 3. CMD => seaJS
export 用于规定模块的对外接口 import 用于输入其他模块提供的功能
m1.js export let school = ''; export function teach(){}
<script type="module"> import * as m1 from "m1.js"; </script>
export{school,teach}
export default{ school:'', change:function(){} }
1. 通用的导入方式 import * as m1 from "m1.js"; 2. 解构赋值形式 import {school,teach} from "m1.js"; import {school as guigu,teach} from "m2.js"; import {default as m3} from "m3.js"; 3.简便形式 针对默认暴露 import m3 from "m3.js";
app.js import * as m1 from "m1.js";
<script src="app.js" type="module"></script>
|
babel对ES6模块化代码转换
1 2 3
| 1. 安装工具 babel-cli babel-preset-env browserify(webpack) npx babel src/js -d dist/js --presets=babel-preset-env npx browserify dist/js/app.js -o dist/bundle.js
|
使用jquery
1 2
| npm i jquery import $ from 'jquery'
|
**
async
1 2 3 4 5 6
| async function fn(){ return new Promise((resolve,reject)=>{ reject('失败的错误'); }) }
|
ES8对象方法扩展
1 2
| Object.keys(); Object.entries();
|
ES9对象展开
命名捕获分组
1 2 3 4 5 6 7 8 9 10 11 12
| let str = '<a href="http://www.atguigu.com">尚硅谷</a>' const reg = /<a href="(.*)">(.*)</a>/; const result = reg.exec(str);
const reg = /<a href="(?<url>.*)">(?<text>.*)</a>/; const result = reg.exec(str);
result.groups.url result.groups.text
|
正则扩展-反向断言
1 2 3 4 5 6
| let str = 'JS5211314你知道么555啦啦啦';
const reg = /\d+(?=啦)/;
const reg = /(?<=么)\d+/;
|
正则扩展-dotAll模式
1 2 3 4
|
const reg = /<li>\s+<a>(.*?)</a>\s+<p>(.*?)<\/p>/; const reg = /<li>.*?<a>(.*?)</a>.*?<p>(.*?)<\/p>/gs;
|
ES10
1 2 3 4 5 6
| Object.fromEntries .trimStart() .trimEnd()
.flat() .flatMap()
|
私有属性
1 2 3 4
| class Person{ #name:'张三', age:18 }
|
matchAll
可选链操作符
大整形
1 2
| let n = 521n; BigInt(123);
|
globalThis