class类
本质上依然是构造函数、原型链的语法糖
- 定义类
//类的声明
class Person{
}
//类的表达式
var Animal = class {
}
- 类的构造函数
每个类都可以有自己的构造函数(方法),这个方法的名称是固定的constructor,通过new操作符,操作一个类的时候会调用constructor,每个类只能有一个构造函数。
通过new关键字操作类的时候,会调用constructor函数,执行如下操作:
1、在内存中创建一个新的对象(空对象)
2、这个对象内部的[prototype]属性会被赋值为该类的prototype属性
3、构造函数内部的this,会指向创建出来的新对象
4、执行构造函数的内部代码(函数体代码)
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
}
var p = new Person("why", 18)
console.log(p) //Person { name: 'why', age: 18 }
- 类的方法
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
eating() {
console.log(this.name + "eating")
}
running() {
console.log(this.name + "running")
}
}
var p = new Person("why", 18)
p.eating()
p.running()
let(变量) / const(常量)
let和const不可以重复声明
let和const没有变量提升
let和const不会被添加到window属性中
let和const有块级作用域,块作用域由{}包括,if和switch和for里面的{}都是块级作用域。函数是一个作用域。ES5只有全局作用域和函数作用域,没有块级作用域。
- let
<script>
const btns = document.getElementByTagName('button');
for( let i = 0; i < btns.length; i++){
btns[i].addEventListener('click',function(){
console.log('第'+ i +'个按钮被点击')
})
}
</script>
- const
当修饰的标识符不会被再次赋值时,可以使用const来保证数据的安全性;建议在ES6中,优先使用const。
/***1.const注意一:不可以再次赋值***/
const a = 20;
a = 30; //错误
/***2.const注意二:const修饰的标识必须赋值***/
const name; //错误
/***3.const注意三:常量的含义是指向的对象(内存地址)不能修改,但是可以改变对象内部的属性***/
const obj = {
name = "aaa";
old = 18
}
//obj = {} //会报错
obj.name = "bbb";
obj.old = 25
对象增强写法
const obj = {} //大括号就叫对象字面量
/***1.属性的增强写法***/
const name = "aaa"; //变量
const old = 18;//变量
const obj = { //变量放到对象里保存
name;
old;
}
/***2.函数的增强写法***/
const obj = {
eat : function (){
}
eat (){
}
}
解构
/***数组解构***/
var names = ["abc", "bbc", "cbc"];
//旧:挨个获取元素
var item1 = names[0]
var item2 = names[1]
var item3 = names[2]
//对数组的解构:[]
var [item1, item2, item3] = names
console.log(item1, item2, item3)//abc bbc cbc
//解构后两个元素
var [, itema, itemb] = names
console.log(itema, itemb)//bbc cbc
//解构出一个元素,后面的两个元素放到一个数组中
var [item, ...newnames] = names
console.log(item, newnames) //abc ['bbc', 'cbc']
//解构的默认值
var [itema, itemb, itemc, itemd = 'aaa'] = names
console.log(itemd) //aaa
/***对象解构***/
var obj = {
name: 'why',
age: 18,
height: 1.58
}
//对象的解构:{} key
var { name, age, height } = obj
console.log(name, age, height) //why 18 1.58
//修改name名字
var { name:newname } = obj
console.log(newname) //why
//默认值
var { address = "广州" } = obj
console.log(address) //广州
模板字符串``
Promise
有异步操作的时候,就用Promise对这个异步操作进行封装;使用链式编程
①基本使用
/***第一种写法***/
new Promise((resolve, reject) => {
setTimeout(() => {
//成功的时候调用resolve,拿到结果的时候通过resolve调用
//resolve('hello world')
//失败的时候调用reject,拿到结果的时候通过reject调用
reject('error message')
},1000)
}).then(data => { //只有一个data参数时可以省略小括号
//成功时通过then处理
console.log(data)
}).catch(err => {
//失败时通过catch处理
console.log(err)
})
/***第二种写法***/
new Promise((resolve, reject) => {
setTimeout(() => {
//成功的时候调用resolve,拿到结果的时候通过resolve调用
//resolve('hello world')
//失败的时候调用reject,拿到结果的时候通过reject调用
reject('error message')
},1000)
}).then(data => {//写一个then传入两个函数
console.log(data)
}, err => {
console.log(err)
})
②链式调用
/***基础版***/
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
//1.自己处理10行代码
console.log(res, '第一层的10行处理代码')
//2.对结果进行第一次处理
return new Promise((resolve) => {
resolve(res + '111')
})
}).then(res => {
//3.第一次处理的结果
console.log(res, '第二层的10行处理代码')
//4.对结果进行第二次处理
return new Promise((resolve) => {
resolve(res + '222')
})
}).then(res => {
//5.第二次处理的结果
console.log(res, '第三层的10行处理代码')
})
/***简写版***/
//省略掉new Promise((resolve) => {}
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
//1.自己处理10行代码
console.log(res, '第一层的10行处理代码')
//2.对结果进行第一次处理
return Promise.resolve(res + '111')
}).then(res => {
//3.第一次处理的结果
console.log(res, '第二层的10行处理代码')
//4.对结果进行第二次处理
return Promise.resolve(res + '222')
}).then(res => {
//5.第二次处理的结果
console.log(res, '第三层的10行处理代码')
})
/***最终版***/
//省略掉Promise.resolve
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
//1.自己处理10行代码
console.log(res, '第一层的10行处理代码')
//2.对结果进行第一次处理
return res + '111'
}).then(res => {
//3.第一次处理的结果
console.log(res, '第二层的10行处理代码')
//4.对结果进行第二次处理
return res + '222'
}).then(res => {
//5.第二次处理的结果
console.log(res, '第三层的10行处理代码')
})
/***失败***/
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('aaa')
},1000)
}).then(res => {
//1.自己处理10行代码
console.log(res, '第一层的10行处理代码')
//2.对结果进行第一次处理
return Promise.reject('err message')
// throw 'err message' //抛出异常,两种写法都可以
}).then(res => {
//3.第一次处理的结果
console.log(res, '第二层的10行处理代码')
//4.对结果进行第二次处理
return res + '222'
}).then(res => {
//5.第二次处理的结果
console.log(res, '第三层的10行处理代码')
}).catch(err => {
console.log(err)
})
③all方法使用
//需要发送两次请求
Promise.all([
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result1')
},2000)
}),
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('result2')
},1000)
})
]).then(results => {
console.log(results)
})
箭头函数
①使用方法
//1.定义函数的方式:function
const aaa = function() {
}
//2.对象字面量增强写法
const obj = {
//第一种
bbb: funciton(){}
//第二种
bbb(){}
}
//3.箭头函数
const ccc = (参数列表) => {
}
/*没有参数时*/
const aaa = () => {
}
/*有两个参数时*/
const sum = (num1, num2) => {
return num1 + num2
}
/*只有一个参数时,参数的小括号可省略*/
const power = num => {
return num * num
}
/*函数代码块中只有一行代码时,可省略大括号和return;代码块中有多行代码时正常写大括号*/
const mul = (num1, num2) => num1 * num2
//箭头函数示例
render: h => h(app)
render: (h) => { //只有一个参数时,h的括号可省略
return h(app) //只有一行代码,可以省略大括号和return
}
②箭头函数的this
何时使用箭头函数:把一个函数作为另一个函数的参数接收的时候
结论:箭头函数中的this引用的是最近作用域中的this
const obj = {
aaa() {
setTimeout(function() {
console.log(this) //window
})
setTimeout(() => {
onsole.log(this) //obj对象
})
}
}
obj.aaa();//执行函数