/** let: 变量 1.同一作用域下不能重复声明 2.作用域: 全局作用域 和 块级作用域 {} 3.不进行预解析 const:常量 1.声明必须赋值 2.声明object类型 不能改的是引用地址 块级作用域 {} 解构赋值:(可迭代对象) 1.怎么快速交换a,b的值 let a = 0; let b = 1; [a, b] = [b, a]; 2.字符串的解构赋值 let str = "abc"; let [e, f] = str; // a c 3.数字的解构赋值 let num = 123; let [c, d] = num; // 报错 num is not iterable 展开运算符: 1. let arr1 = [1, 2, 3, 4] let arr2 = ["a", "b", ...arr1, "c", "d"] // ["a", "b", 1, 2, 3, 4, "c", "d"] 2.剩余参数 let [a, b, ...c] = arr1; console.log(a, b, c) // 1, 2, [3, 4] 3.避免对象修改的是同一引用地址 let obj = {a:1} let obj2 = {...obj} Set对象 构造函数 用来构建某一类型的对象 对象的实例化 let arr = [1, 2, 3, 4, 1, 2, "a"] let s = new Set(arr) // 参数:数组 or 类数组, 去重 arr = [...s] s.size() // 数值的个数 ==> length s.clear() // 清空 s.delete("a") // 删除某一项 s.add(6).add('b') // 添加某一项,返回set对象,支持链式 s.has("a") // 是否包含某一项 Map对象 let arr = [ ["a", 1], ["b", 10], ["c", 100] ] let m = new Map(arr) m.get(key); //取值 m.set(key, value); // 添加 函数的扩展 1.箭头函数 2.不定参数 arguments function fn() { console.log(arguments) } fn(1,2) const fn1 = () => { console.log(arguments) // 报错,箭头函数没有不定参数,解决方法:rest参数 } const fn1 = (...arg) => { console.log(arg) // rest参数 } 3.this问题 箭头函数本身没有this,调用箭头函数的this时,指向的是其声明时所在的作用域的this 4.参数默认值 数组的新增方法: 1.构造函数下的方法 1.1 Array.form() 把一个类数组转换成真正的数组,接收三个参数:类数组、遍历回调函数、this指向 { let lis = document.querySelectorAll("#list li"); let arr = []; lis = Array.form(lis, function(item, index) { console.log(item, index, this); return index; }, arr); console.log(lis) } 1.2 Array.of() 将参数转成一个数组 { Array.of(1, 2, "a", "b") // [1, 2, "a", "b"] } 1.3 Array.isArray() 检测数据是否是个数组 2.数组对象本身的方法 let arr = new Array(); 2.1 arr.find() // 查找数组中满足要求的第一个元素, 返回具体的值 参数1:回调函数 参数2:回调函数的this指向 { let arr = ["a", "b", "c"] let arr = [1, 2, 3, 4] let val = arr.find((item, index) => { if(item >= 3) { return true } }); console.log(val) // 3 } 2.2 arr.findIndex() // 返回索引 2.3 arr.flat() // 扁平化多维数组。传参:层级,或者Infinity,不传默认一层 { const arr =[ ["小明", 18], [["ew","ewrwer"], [343, 34324]] ] arr.flat() } 2.4 arr.flatMap() //与深度为1的flat作用几乎相同 { let arr = [ ["小明", "34"] ["xiaohua", "12"] ] let newArr = arr.flatMap((item, index) => { console.log(item, index) return item; }) console.log(newArr) } 2.5 arr.fill() // 填充 { let arr = [0, 1, 2, 3, 4] arr.fill("a", 1, 3) // 从索引1开始填充,索引3截止 [0, "a", "a", 3, 4], 默认值是arr.length } 2.6 arr.includes() { let arr = ["a", "b", "c"] arr.includes("c", 2) // true 从索引2开始检索 } 字符串新增的方法 1.includes 2.startsWith('ab', 2) // 从索引2开始查找ab开始的字符串,返回布尔值 3.endsWith() // 以xx结束 4.repeat() // 传入数字,重复n次 5.模板字符串 对象新增的方法 1.简洁表示法 let a = 2; let b = 232; let obj = { a, b, c() { // ... } } 2.属性名表达式(给属性名赋值) let name = '小明'; let obj = { [name]: 111 } console.log(obj) // let obj = { // '小明': 111 // } 3. Object.assign() 4. Object.is(value1, value2) // 判断两个值是否是相同的值 console.log(+0 === -0) // true console.log(Object.is(+0, -0)) // false console.log(Object.is(1, "1")) // false console.log(Object.is(NaN, NaN)) // true 两个值都是 undefined 两个值都是 null 或者都是 false 两个值是 由相同个数的字符 按照相同的顺序 组成的字符串 两个值指向同一个对象 两个值都是 数字 并且 都是 +0 都是 -0 都是 NaN babel 迭代器 1.迭代协议:规定了迭代与实现的逻辑 2.迭代器:具体的迭代实现逻辑 3.迭代对象:可被迭代的对象-实现了[Symbol.iterator]方法 4.迭代语句 for ... in: 以原始插入的顺序迭代对象的可枚举属性 for ... of: 根据迭代对象的迭代器具体实现迭代对象数据 5.迭代器实现原理 5.1 obj[Symbol.iterator] = function() { return { next() { return { value: '11', // 循环过程中的值 done: false // true循环结束 false循环未完成 } } } } 5.2 for...in 遍历数组,拿到的是下标 let arr = ["a", "b", "c"] for(let attr in arr) { console.log(attr) // 0 1 2 } 5.3 for...of 遍历数组,拿到的是value let arr = ["a", "b", "c"] for(let attr of arr) { console.log(attr) // a b c } 5.4 for...in 遍历对象,拿到的是属性名 let obj = { a: '2323', b: 'wewr', } for(let attr in obj) { console.log(attr) // a b } 5.5 for...of 遍历对象,报错 let obj = { a: '2323', b: 'wewr', } for(let attr of obj) { console.log(attr) // Uncaught TypeError: obj is not iterable } 可迭代对象不可迭代对象,区别在于是否定义了迭代器 Symbol.iterator let obj = { a: 1, b: 2, c: 3, } for(let val of obj) { // 迭代协议(条件) let values = Object.values(obj); let index = 0; obj[Symbol.iterator] = function() { return { next() { if(index >= values.length) { return { done: ture // true循环结束 } } else { return { done: false, value: values[index++] } } } } } } // 撸一下,手动模拟过程(for...of相当于把此过程执行了一遍,不停的调用next方法) let values = obj[Symbol.iterator](); values.next() // {done: false, value: 1} values.next() // {done: false, value: 2} values.next() // {done: false, value: 3} values.next() // {done: true} Generator 函数 在形式上,Generator是一个普通函数,但是有两个特征。 一是,function命令与函数名之间有一个星号 二是,函数体内部使用yield语句,定义遍历器的每个成员,即不同的内部状态 function*fn() { yield 1; yield 2; yield 3; } let f = fn(); // console.log(f); // 返回一个Generator函数 // f.next(); // {value: 1, done: false} for(let val of f) { console.log(val) // 1 2 3 } // 改写 function*fn() { yield new Promise((resolve, reject) => { setTimeout(() => { console.log(1); resolve("第一个yeild执行完毕"); }, 200); }); yield new Promise((resolve, reject) => { setTimeout(() => { console.log(1); resolve(); }, 200); }); yield new Promise((resolve, reject) => { setTimeout(() => { console.log(1); resolve(); }, 200); }); } co(fn); function co(fn) { let f = fn(); next(); function next() { let result = f.next(); if(!result.done) { // 上一个异步走完了,再执行下一个异步 result.value.then((info) => { console.log(info) next(); }) } } }