# 基础语法# let变量不能重复声明 let 是块级作用域,位于代码块中,代码块外没有定义 不存在变量提升,初始不会对 let 定义的变量进行收集,赋予 undefined 初值 不影响作用域链,如果在代码块中调用了函数,如果在该函数中找不到变量定义,则会到上一级,也就是块级作用域中找到 let 定义的变量 # constconst 用来声明常量,一定要赋初值 值一旦被确定就不能修改,且一般变量名使用大写 也是一个块级作用域 对于数组和对象的元素修改,不算做对常量的修改,不会报错,是因为常量所指向的起始地址没有发生改变。javascript 1 2 const TEAM = ['a' ,'b' ,'c' ,'d' ];TEAM.push('e' );
上面的代码不会报错,但下面的代码就会报错:javascript # 解构赋值解构赋值:允许按照一定模式从数组和对象中提取值,对变量进行赋值。
数组的解构javascript 1 2 const F4 = ['a' ,'b' ,'c' ,'d' ];let [a, b, c, d] = F4;
对象的解构javascript 1 2 3 4 5 6 7 8 9 10 const a = { name : 'osakana' , age : '20' , click : function ( ) { console .log('hello' ); } }; let {name, age, click} = a;click();
执行如上代码就会在控制台输出 hello # 模板字符串ES6 引入新的声明字符串的方式:反单引号 (``)
内容中可以直接出现换行符,而普通的引号不能 变量拼接javascript 1 2 let love = 'czj' ;let out = `${love} 是我最爱的女孩!` ;
# 箭头函数ES6 允许使用箭头 (=>) 定义函数
javascript 1 2 3 4 5 6 7 8 let fn = (a, b ) => { ...... } fn(1 ,2 );
箭头函数的特性:
this 是静态的,this 始终指向函数声明时所在作用域下的 this 的值 不能作为构造函数实例化对象 不能使用 arguments 变量(用来保存实参) 箭头函数的简写省略小括号,当形参有且只有一个时javascript 1 2 3 let add = n => { return n + n; }
省略花括号,当代码体只有一条语句时,此时 return 必须省略,语句的执行结果就是函数的返回值javascript 箭头函数适合与 this 无关的回调、定时器,数组的方法回调;不适合与 this 有关的回调、事件回调、对象的方法 # rest 参数ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments
javascript 1 2 3 4 function date (...args ) { console .log(args); } date('a' ,'b' ,'c' );
上面的代码会返回一个数组 ['a','b','c'],rest 参数必须要放到参数最后
javascript 1 2 3 function date (a,b,...args ) {}
# 扩展运算符[...] 扩展运算符能将数组转换为逗号分隔的参数序列
javascript 1 2 3 4 5 6 7 const array = ['1' ,'2' ,'3' ]; function hanshu ( ) { console .log(arguments ); } hanshu(...array);
# SymbolSymbol 是一种 ES6 新引入的原始数据类型,表示独一无二的值。类似于字符串的数据类型。
Symbol 特点:
值唯一,用来解决命名冲突的问题 值不能与其他数据进行运算 定义的对象属性不能使用 for...in 循环遍历,但是可以使用 Reflect.ownKeys 来获取对象的所有键名
javascript 1 2 3 4 5 6 7 8 let s = Symbol ();let s1 = Symbol ('a' );let s2 = Symbol ('a' );console .log(s1 === s2) let s3 = Symbol .for('a' );let s4 = Symbol .for('a' );console .log(s3 === s4)
Symbol 可以用来向对象中添加方法
javascript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 let game = {···}let methods = { up : Symbol (), down : Symbol () }; game[methods.up] = function ( ) { console .log("up" ); } game[methods.down] = function ( ) { console .log("down" ); } let game = { name : "overwatch" , [Symbol ('say' )]: function ( ) { console .log("hello" ); } }
Symbol 还有 11 个内置属性,这里仅举个例子:
javascript 1 2 3 4 5 6 7 8 9 class Person { static [Symbol .hasInstance](param){ console .log(param); return false ; } } let test = {};console .log(test instanceof Person);
# 迭代器ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供 for...of 消费。
javascript 1 2 3 4 5 6 const array = ['a' ,'b' ,'c' ,'d' ];for (let v of array) { console .log(v); }
会输出 array 数组中的每个元素的值。
# 迭代器的工作原理创建一个指针对象,指向当前数据结构的起始位置 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员 每调用 next 方法返回一个包含 value 和 done 属性的对象
javascript 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 osakana = { name : "osakana373" , stu : [ 'xiaoming' , 'xiaowang' , 'xiaozhang' ], [Symbol .iterator](){ let index = 0 ; let _this = this ; return { next : function ( ) { if (index < _this.stu.length) { const result = {value : _this.stu[index], done : false }; index++; return result; }else { return {value : undefined , done : true }; } } }; } } for (let v of osakana) { console .log(v); }
上面的代码会输出 stu 数组中的每一个元素。
# 生成器生成器是一个特殊函数,用来进行异步编程,格式如下:
javascript 1 2 3 4 5 6 7 8 9 10 function * gen ( ) { console .log("hello" ); } for (let v of gen()){ console .log(v); }
只有调用迭代器的 next 方法才会打印 hello,或者使用 for...of 语句遍历。生成器也可以传参。
# PromisePromise 是 ES6 引入的异步编程的新解决方案,语法上是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
javascript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 const p = new Promise (function (resolve, reject ) { setTimeout (function ( ) { let data = '数据库数据' , resolve(data); }, 1000 ) }); p.then(function (value ) { }, function (reason ) { })
# Promise 读取文件这里用到了一些 node.js 的知识(详情可以看菜鸟教程 Node.js ),不过不会问题也不大。
javascript 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 const fs = require ('fs' );fs.readFile('./xxx/xxx' , (err, data ) => { if (err) throw err; console .log(data.toString()); }); const p = new Promise (function (resolve, reject ) { fs.readFile('./xxx/xxx' , (err, data ) => { if (err) reject(err); resolve(data); }); }); p.then(function (value ) { console .log(value.toString()); }, function (reason ) { console .log("读取失败" ); });
# Promise 封装 AJAX 请求我们假设接口地址为:https://api.apiopen.top/getJoke
javascript 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 const p = new Promise ((resolve, reject ) => { const xhr = new XMLHttpRequest(); xhr.open("GET" , "https://api.apiopen.top/getJoke" ); xhr.send(); xhr.onreadystatechange = function ( ) { if (xhr.onreadystatechange === 4 ) { if (xhr.status >= 200 && xhr.status < 300 ) { resolve(xhr.response); }else { reject(xhr.status); } } } }); p.then(function (value ) { console .log(value); }, function (reason ) { console .error(reason); });
# Promise.prototype.then 方法
javascript 1 2 3 4 5 6 7 8 9 10 11 12 const p = new Promise ((resolve, reject ) => { setTimeout (()=> { resolve('用户数据' ); }, 1000 ) }); const result = p.then(value => { console .log(value.toString()); }, reason => { console .log("读取失败" ); });
# catch 方法catch 方法用来指定失败的回调
javascript 1 2 3 4 5 6 7 8 9 10 const p = new Promise ((resolve, reject ) => { setTimeout (()=> { reject('出错啦' ); }, 1000 ) }); p.catch(function (reason ) { console .warn(reason); });
# SetES6 提供了新的数据结构 Set(集合)。类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,故可使用扩展运算符合 for...of 进行遍历。
Set 的属性和方法:
size 返回集合的元素个数 add 增加一个新元素,返回当前集合 delete 删除元素,返回 boolean 值 has 检测集合中是否包含某个元素,返回 boolean 值
javascript 1 2 3 4 5 6 7 8 9 let s = new Set ();let s1 = new Set (['a' ,'b' ,'c' ,'a' ]);s1.add('d' ); s1.delete('d' ); s1.has('d' ); for (let v of s1) { console .log(v); }
# MapES6 提供了 Map 数据结构,类似于对象,也是键值对的集合。但是 “键” 的范围不限于字符串,各种类型的值(包括对象)都可以当做键。Map 也实现了 iterator 接口,故可使用扩展运算符合 for...of 进行遍历。
Map 的属性和方法:
size 返回 Map 的元素个数 set 增加一个新元素,返回当前 Map get 返回键名对象的键值 has 检测 Map 中是否包含某个元素,返回 boolean 值 clear 清空集合,返回 undefined
javascript 1 2 3 4 5 6 7 let m = new Map ();m.set('name' , 'osakana' ); m.set('change' , function ( ) { console .log("Hello" ); });
# Class 类
javascript 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 Phone (brand, price ) { this .brand = brand; this .price = price; } Phone.prototype.call = function ( ) { console .log("call" ); } let Huawei = new Phone('华为' , 4999 );Huawei.call(); console .log(Huawei);class Phone { constructor (brand, price ) { this .brand = brand; this .price = price; } call ( ) { console .log("call" ); } } let Huawei = new Phone('华为' , 4999 );
# class 类的静态成员类的静态成员属于这个类,不属于这个类的实例
javascript 1 2 3 4 5 6 7 8 9 10 11 class Phone = { static name = '手机' ; static change ( ) { console .log("xxx" ); } } let Huawei = new Phone();console .log(Huawei.name); console .log(Phone.name);
# 构造函数继承
javascript 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 function Phone (brand, price ) { this .brand = brand; this .price = price; } Phone.prototype.call = function ( ) { console .log("call" ); } function SmartPhone (brand, price, color, size ) { Phone.call(this , brand, price); this .color = color; this .size = size; } SmartPhone.prototype = new Phone; SmartPhone.prototype.constructor = SmartPhone; SmartPhone.prototype.photo = function ( ) { console .log(); } const Huawei = new SmartPhone('Huawei' , 4999 , '星河银' , '6.7inch' );
# 类继承
javascript 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 class Phone { constructor (brand, price ) { this .brand = brand; this .price = price; } call ( ) { console .log("call" ); } } class SmartPhone extends Phone { constructor (brand, price, color, size ) { super (brand, price); this .color = color; this .price = price; } photo ( ) { consolo.log(); } call ( ) { console .log("hello" ); } } const Huawei = new SmartPhone('Huawei' , 4999 , '星河银' , '6.7inch' );
# class 中的 getter 和 setter 设置get 和 set 通常对对象的动态属性进行封装。
javascript 1 2 3 4 5 6 7 8 9 10 class Phone { get price (){ console .log(); } set price (newVal ){ console .log(); } }
# 数值扩展Number.EPSILON 是 js 表示的最小精度 二进制、八进制和十六进制:0bxxx 0oxxx 0xxxx Number.isFinite () 检测一个数值是否为有限数 Number.isNaN () 检测一个数值是否为 NaN Number.parseInt () 字符串转整数(会截断) Number.isInteger () 判断一个数是否为整数 Math.trunc () 将数字的小数部分抹掉 Math.sugn () 判断一个数是否为正数负数还是 0(1,-1,0) # 对象方法扩展Object.is (a, b) 判断两个值是否完全相等Object.assign () 对象的合并,相同属性后面对象会覆盖前面对象 Object.setPrototypeOf (a, b) 设置原型对象,b 是 a 的原型对象 Object.getPrototypeOf 获取一个对象的原型对象 Object.keys () 获取对象所有的键 Object.values () 获取对象所有的值 Object.entries () 返回一个数组,数组中每个成员还是一个数组 Object.getOwnPropertyDescriptors () 获取对象属性的描述对象 # ES8 新特性# async 和 awaitasync 和 await 两种语法结合可以让异步代码像同步代码一样
# async 函数async 函数的返回值为 promise 对象 promise 对象的结果由 async 函数执行的返回值决定 # await 表达式await 必须写在 async 函数中 await 右侧的表达式一般为 promise 对象 await 返回的是 promise 成功的值 await 的 promise 失败了,就会抛出异常,需要通过 try...catch 捕获处理
javascript 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const p = new Promise ((resolve, reject ) => { resolve("成功的值!" ); }) async function main ( ) { try { let result = await p; console .log(result); } catch (e) { console .log(e); } } main();
上面的代码会输出 "成功的值!"
# async 和 await 封装 AJAX 请求
javascript 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 function senfAJAX (url ) { return new Promise ((resolve, reject ) => { const x = new XMLHttpRequest(); x.open('GET' , url); x.send(); x.onreadystatechange = function ( ) { if (x.readyState === 4 ) { if (x.status >= 200 && x.statue < 300 ) { resolve(x.response); } else { reject(x.status); } } } }) } sendAJAX("https://api....." ).then(value => { console .log(value); }, reason => {}) async function main ( ) { let result = await sendAJAX("https://api....." ); console .log(result); }
# ES9 新特性# 对象展开ES9 中为对象提供了像数组一样的 rest 参数和扩展运算符
javascript 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 function connect ({host, port, ...user} ) { console .log(host); console .log(port); console .log(user); } connect({ host : '127.0.0.1' , port : 3306 , username : 'root' , password : 'root' }); const one = { q : 'a' } const two = { w : 'b' } const three = { e : 'c' } const four = { r : 'd' } const result = {...one, ...two, ...three, ...four}