# ECMAScript6 常用语法
# let关键字
与var类似, 用于声明一个变量。在块级作用域内有效,不能重复声明,不会预处理,不存在提升
for (let i=0; i<btns.length; i++) {
btns[i].onclick = function () {
console.log(i) // 因为是块级作用域,所以事件能拿到for循环i的值
}}
# const关键字
定义常量,不能修改,其它特点同let,可以原来保存一些不用改变的数据
const KEY = 'CBA'
KEY = 'DB' // 报错
# 变量解析赋值
从对象或数组中提取数据, 并赋值给变量(多个)
// 对象的解构赋值
let {n, a} = {n:'tom', a:12} // n = tom a = 12
// 数组的解构赋值
let [a,b] = [1, 'atguigu']; // a = 1 b = atguigu
# 模板字符串
简化字符串的拼接
let a = 900
let str = `这个月消费了${a}元` // 这个月消费了900元
# 简化对象属性写法
let username = '弟兄姐妹'
let age = 410
let obj = {username,age}
// obj.username = 弟兄姐妹
// obj.age = 410
# 简化对象方法写法
let obj = {
getName() {console.log('函数1执行')},
getName2() {console.log('函数2执行')}
}
# 箭头函数
简洁定义方法()=>{}
,箭头函数没有自己的this,箭头函数的this不是调用的时候决定的,而是在定义的时候处在的对象就是它的this,箭头函数的this看外层的是否有函数,如果有,外层函数的this就是内部箭头函数的this,如果没有,则this是window。
形参的情况
// 1.没有形参的情况
let fun1 = () => console.log('我是箭头函数')
fun1()
// 2.只有一个形参的情况,()可以省略
let fun2 = a => console.log(a)
fun2('xxx')
// 3.两个,或两个以上的情况,()不可以省略
let fun3 = (x, y) => console.log(x, y)
fun3(31,56)
函数体的情况
// 1.函数体只有一条语句或是表达式的时候,{}可以省略---->会自动返回执行结果
let fun4 = (x, y) => x + y;
console.log(fun4(36, 64))
// 2.函数体不止有一条语句或是表达式的时候,{}不可以省略
let fun5 = (x, y) => {
console.log(x, y)
return x + y
}
console.log(fun5(36, 64))
# 扩展运算符
取代arguments ,比 arguments 灵活,只能是最后部分形参参数
function fun(...values) {console.log(values)} // values = [6,7,8,9,1,6,3,5]
fun(6,7,8,9,1,6,3,5)
数组中插入另一个数组的元素
let arr1 = [1,3,5];
let arr2 = [2,...arr1,6]; // [2,1,3,5,6]
arr2.push(...arr1); // [2,1,3,5,6,1,3,5]
# 形参默认值
function point(x=0, y=0) {
console.log(x,y)
};point() // 0 0
# 字符串前后查找
let s = 'Hello world!';
const [a, b, c] = [
s.startsWith('Hello', 2),
s.endsWith('!'),
s.includes('o w')
];
console.log(a, b, c); // false true true
# ECMAScript6 高级语法
# Promise 对象
代表了未来某个将要发生的事件(通常是一个异步操作),有了promise对象, 可以将异步操作以同步的流程表达出来, 避免了层层嵌套的回调函数(俗称'回调地狱')
ES6的Promise是一个构造函数, 用来生成promise实例
// 创建promise对象
let promise = new Promise((resolve, reject) => {
if(异步操作成功) { //执行异步操作
resolve(value);//修改promise的状态为fullfilled
} else {
reject(errMsg);//修改promise的状态为rejected
}
})
// 调用promise的then()
promise.then(function(
result => console.log(result), // 异步成功时函数
errorMsg => alert(errorMsg) // 异步失败时函数
))
promise对象的3个状态
pending:
初始化状态
fullfilled:
成功状态
rejected:
失败状态
使用promise封装处理ajax链式请求
// 兼容XMLHttpRequest请求方法
function getHTTPObject(){....}
function getNews (method, url) {
let promise = new Promise((resolve, reject)=>{// 创建promise实例
let request = getHTTPObject();// 创建一个XMLHttpRequest 对象
request.open(method,url); // 规定发送格式
request.send(null); // 发送请求
request.onreadystatechange = () => { // 响应函数
if(request.readyState == 4 && request.status == 200 || request.status == 304) {
resolve(request.responseText)
}else{reject('暂时不存在此信息')}// 响应不可用,将数据传入promise的回调函数reject中
})
return promise // promise定义好ajax后返回
}}
getNews('GET', 'http://localhost:3000/news?id=2')
.then((data)=>{ // 接收第一个数据
console.log(JSON.parse(data))
let url = JSON.parse(data).commentsUrl // 接收下一个ajax
return getNews('GET', `http://localhost:3000${url}`) // 定义下一个请求,并将其返回
}, (error)=>{console.log(error)})
.then((data)=>{ // 返回值是一个promise对象,这样就可以接收第二个数据
console.log(JSON.parse(data))
},(error)=>{console.log(error)})
# symbol 原始数据类型
Symbol属性对应的值是唯一的 Symbol值不能与其他数据进行计算,包括同字符串拼串 for in, for of遍历时不会遍历symbol属性。
// symbol可以添加标识Symbol([标识]),number,string
let key = Symbol('key')
let obj = {
[key]: 60, // ES6语法
username: '徐晓东',
age: 60
}
console.log(obj[key]) // obj[sym] = 60
// 获取对象中的sym属性,ES6有特定方法
console.log(Object.getOwnPropertySymbols(obj))
// Symbol的for方法声明Symbol
let s5 = Symbol.for('test') // 没有这个变量则声明一个
let s6 = Symbol.for('test') // 如果已经存在了.则获取这个sym
# generator 状态机函数
function* myGenerator () {
console.log('开始执行')
let result = yield 'hello'
console.log(result)
console.log('暂停后,继续执行')
yield 'gener'
console.log('执行完毕')
return '返回的结果'
}
let MG = myGenerator()
console.log(MG.next()) // 开始执行
console.log(MG.next('aaaaaaaaaaaaaaaaaaaaa')) // aaaaaaaaaaaaaaaaaaaaa hello 暂停后进行执行
console.log(MG.next()) // 执行完成 返回的结果
# symbol.iterator 遍历器
iterator是一种接口机制,为各种不同的数据结构提供统一的访问机制,使得数据结构的成员能够按某种自定义次序排列
工作原理:
- 创建一个指针对象(遍历器对象),指向数据结构的起始位置。
- 第一次调用next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针会一直往后移动,直到指向最后一个成员
- 每调用next方法返回的是一个包含value和done的对象,{value: 当前成员的值,done: 布尔值}
* value表示当前成员的值,done对应的布尔值表示当前的数据的结构是否遍历结束。
* 当遍历结束的时候返回的value值是undefined,done值为false
自定义送代器
let targetData = {
[Symbol.iterator]: function () {
let nextIndex = 0
console.log(this)
return {
next () {
console.log(this)
let bool = nextIndex < this.length
return {value: (bool ? this[nextIndex++]:undefined), done: !bool}
}
}
},
username: '60',
age: 50
}
for (let i of targetData) {
console.log(i)
}
状态机自定义送代器
var myIterable = {}
myIterable[Symbol.iterator] = function* () {
yield 1;
yield 2;
yield 3;
}
[...myIterable] // [1, 2, 3]
# async 同步流程表达异步函数
function foo() {return new Promise(resolve => {setTimeout(resolve, 2000)})}
async function test() {
console.log('开始执行', new Date().toTimeString())
await foo() // 当前的promise操作完成就往下执行
console.log('执行结束', new Date().toTimeString())
};test()
# class 类定义构造方法
class Person {
// 类的构造方法
constructor(name, age) {
this.name = name
this.age = age
}
// 类的一般方法
showName() {console.log(this.name, this.age)}
}
let person = new Person('大学生', 60)
class继承父类属性与方法
// 继承父类属性与方法
class StarPerson extends Person {
constructor(name, age, salary){
super(name, age) // 调用父类的构造函数
this.salary = salary // 在父类的元素上新添加salary元素
}
showName() {
console.log('调用子类方法')
console.log(this.name, this.age, this.salary)
}
}
let p1 = new StarPerson('小学生', 70, 3000000000)
class static 定义静态方法
class ClassWithStaticMethod {
static staticMethod() {
return 'static method has been called.';
}
}
console.log(ClassWithStaticMethod.staticMethod());
// expected output: "static method has been called."
class getter setter 定义属性符
class Phone {
get price() {
console.log('价格属性被读取了')
return 'iloveyou'
}
set price(newVal) {
console.log('价格属性被修改了')
}
}
let s = new Phone()
console.log(s.price) // > 价格
# Proxy 生成代理对象
根据对象代理属性
const obj = {
username: '毛先生',
password: 123456,
[Symbol('secret')]: 'I am scared!',
}
const observer = new Proxy(obj, {
/**当获取proxy对象属性时的捕捉器
* @param {object} target 目标对象
* @param {string} property 目标属性名称
* @param {object} receiver 最初被调用的对象。通常是 proxy 本身
*/
get(target, property, receiver) {
// console.log('属性值获取: ', target[property])
// console.log('receiver: ', receiver)
return target[property]
},
/**当设置proxy对象属性时的捕捉器
* @param {object} target 目标对象
* @param {string} property 目标属性名称
* @param {any} value 设置的属性值
* @param {object} receiver 最初被调用的对象。通常是 proxy 本身
*/
set(target, property, value, receiver) {
return value
},
/**当 key in proxy 时的拦截器
* @param {object} target 目标对象
* @param {string} key in传入的key值
* @returns {Boolean}
*/
has(target, key) {
return key in target
},
/**当 delete propxy 属性时的拦截器
* @param {object} target 目标对象
* @param {string} property 待删除的属性名称
* @returns {Boolean} 是否删除成功
*/
deleteProperty(target, property) {
return true
},
/**当调用 Reflect.ownKeys 时的拦截器
* @param {object} target 目标对象
*/
ownKeys(target) {
return Reflect.ownKeys(target)
}
})
根据函数代理参数与调用
function sum(a, b) { return a + b; }
const HandlerFunction = new Proxy(sum, {
/**函数调用的拦截器
* @param {Function} target 目标方法
* @param {object|undefined} thisArg 调用时上下文
* @param {Array<any>} args 参数组成的数组
* @returns {any} 返回值将作为函数返回值使用
*/
apply(target, thisArg, args) {
return args[0] + args[1] * 10
},
/**new操作符的拦截
* @param {Function} target 目标对象
* @param {Array<any>} args 参数组成的数组
* @param {newTarget} newTarget 最初被调用的构造函数
*/
construct(target, args, newTarget) {
return new target(...args);
}
})