## let关键字
定义一个变量
特征:
1、不能重复声明
2、块级作用域
3、不存在变量提升
4、暂存死区
## const关键字
定义一个常量
特征:
1、const关键字定义的值不能修改
2、不能重复声明
3、块级作用域
4、不存在变量提升
5、暂存死区
## 解构赋值
### 数组的解构
数组按位置解构变量
```javascript
let arr = [5,7,4];
let [a,b,c] = arr;
// 相当于
let a = arr[0];
let b = arr[1];
let c = arr[2];
```
### 扩展运算符
```javascript
let [a1,b1,...c1] = [1,2,3,4,5,6]
console.log(a1) // 1
console.log(c1) // [3,4,5,6] // 扩展运算符的作用就是把解构后剩余的部分赋值给扩展运算符
```
### 结构运算的默认值
```javascript
let arr2 = [1,2];
let [a2=0,b2,c2=9,d2=100] = arr2;
console.log(a2) // 1
console.log(b2) // 2
console.log(c2) // 9
console.log(d2) // 100
let [aa=10,bb=9,cc=8] = [1,null,undefined]
```
### 对象的解构
按键解构变量
```javascript
let obj = {
name:'xiaoming',
age:18,
sex:'男'
}
let {age,name,sex} = obj
console.log(name)
console.log(age)
console.log(sex)
```
### 扩展运算符
```javascript
let obj = {fashi:'安其拉',cike:'兰陵王',tanke:'俄洛伊',adc:'寒冰'};
let { cike, ...oth} = obj;
console.log(cike)
console.log(oth)
```
### 字符串的解构赋值
字符串的解构赋值是按照数据的解构赋值方法进行解构
```javascript
let str = 'hello world';
let [a,b,c,...d] = str;
console.log(a) // 'h'
console.log(b) // 'e'
console.log(c) // 'l'
console.log(d) // ['l','o',' ','w','o','r','l','d']
```
## 模板字符串
在es6中使用一对反引号 (``) 定义一个模板字符串
模板字符串的两个特征:
1、长字符串可以换行
2、在模板字符串中可以插入变量
```javascript
let num = 18;
let con = `<div>
<p>
<span>
我是个模板字符串
我今年 ${num} 岁
</span>
</p>
</div>`;
```
## 箭头函数
使用 ()=>{} 代替原来的 function(){} 的形式定义的函数叫做箭头函数。
箭头函数的特点:
```javascript
// ()代表参数体 {} 函数体
let add = (a,b)=>{
return a+b
}
console.log(add(2,3))
// 当箭头函数的参数只有一个时 () 可以省略
let say = t => {
console.log(t)
}
say('今天天气不错')
// 当函数体代码只有一行时 {} 可以省略
let add1 = (a,b) => console.log(a+b);
add1(3,4)
// 如果 不加 {} 函数体代表return
let add2 = (a,b) => a+b
let n = add2(5,6)
var name = '张三'
console.log(window.name)
let xiaoming = {
name:'小明',
age:18,
say:function(){
console.log('我叫'+this.name)
},
// 箭头函数没有this 保留this关键字
say1:e=>{
console.log('我叫'+this.name)
}
}
xiaoming.say()
xiaoming.say1()
// 函数的arguments可以获取传入的所有参数
let fn = function(a,b,c,d){
console.log(arguments)
}
fn(1,2,3,4) // [1,2,3,4]
// 箭头函数没有arguments参数
let fn1 = (a,b,c,d)=>{
console.log(arguments) // undefined
}
fn1(4,5,6,7)
```
## es6扩展方法
### 字符串的扩展
```javascript
// padStart 在字符串前填充某字符串到某长度
console.log("i".padStart(3,'hello')) // hei
console.log("i".padStart(10,'hello')) // hellohelli
// padEnd 在字符串后填充某字符串到某长度
console.log("i".padEnd(7,'hello')) // ihelloh
console.log("i".padEnd(3,'hello')) // ihe
// startsWith 判断是否以某字符串开头
let str = "An apple is an apple";
console.log(str.startsWith('a')) // false
console.log(str.startsWith('A')) // true
// endsWith 判断是否以某字符串结尾
console.log(str.endsWith('a')) // false
console.log(str.endsWith('n apple')) // true
// includes 判断一个字符串是否包含某字符串
str.includes('an apple') // true
```
### 数组的扩展
```javascript
// Array.from 把一个类数组转换成数组 类数组:键是数字 + length属性
let obj = {
0:4,
3:6,
6:1,
9:9,
length:5
}
console.log(obj)
console.log(Array.from(obj))// array
// fill 以特定内容填充数组
let arr = new Array(10) // 以构造方法创建数组时 参数只传一个数字时 代表数组的长度
arr.fill('2') // ['2' x 10]
arr=[1,2,3,4,5,6,7,8]
// fill接收三个参数:要填充的内容 开始填充的位置 结束的位置
arr.fill('2',0,3)
console.log(arr) // ['2','2','2',4,5,6,7,8]
// includes 判断数组中是否包含某元素
arr=[1,2,33,4,55,6,7,8];
console.log(arr.includes(4)) // true
console.log(arr.includes(44)) //false
// keys 获取数组中的所有键 组成新数组
for(let i of arr.keys()){
console.log(i) // 每个数据的下标
}
// values 获取数组中的所有值 组成新数组
for(let i of arr.values()){
console.log(i) // 每个数据的值
}
// entries 获取每一组键和值
for(let [k,v] of arr.entries()){
console.log(k,v)
}
// find 根据条件(回调)按顺序遍历数组,当回调函数返回为true时 find返回对应的第一条数据
let arr = [7,11,4,18,66,33];
// 回调函数接收三个参数:value index arr v是必填
let res = arr.find(function(v,k,arr){
console.log("v:",v)
console.log("k:",k)
console.log("arr:",arr)
return v % 2 == 0
})
console.log('----')
console.log(res) // 4
// findIndex 根据条件(回调)按顺序遍历数组,当回调函数返回为true时 find返回对应的第一条数据的下标
let arr = [7,11,4,18,66,33];
// 回调函数接收三个参数:value index arr v是必填
let res = arr.findIndex(function(v,k,arr){
console.log("v:",v)
console.log("k:",k)
console.log("arr:",arr)
return v % 2 == 0
})
console.log('----')
console.log(res) // 2
// map 依次遍历数组 返回一个处理后的数据
let arr = [7,11,2,18,66,33];
let res = arr.map(function(item){
return item*2
})
console.log(res) // [14,22,4,36,132,66]
// some 检测是否有符合条件的元素 返回布尔值
let arr = [7,11,2,18,66,33];
let res = arr.some(function(item){
return item<2
})
console.log(res) // false
// filter 过滤 当回调返回值为false时 过滤符合条件的值 返回过滤的值
let arr = [7,11,2,18,66,33];
let res = arr.filter(function(item){
return item<10
})
console.log(res) // [7,2]
```
### 数值的扩展
```javascript
// parseInt 转换成整数型
console.log(window.parseInt('1.23')) // 1
console.log(window.parseInt(12.3)) // 12
console.log(Number.parseInt(1.23)) // 1
//parseFloat 转换成浮点型
console.log(Number.parseFloat('1.23')) // 1.23
// isNaN判断是否不是数值类型 es之后将其挂载到Number上 而不是window
// isFinite 判断是否是数值类型
// Number.isSafeInteger 判断是否是有效数字
// 有效数字的取值范围是:-2^53-1 ~ 2^53-1
// 在es6中使用Number.MAX_SAFE_INTEGER 和 Number.MIN_SAFE_INTEGER 获取最大有效值和最小有效值
// 幂的运算 ** 从右向左运算
2**10**0 // 2
(2**10)**0 // 1
es6之后 使用 0o 开头定义16进制
使用 0b 开头定义2进制
```
## Promise
promise是对一个异步操作最终状态的一个解释(要么成功,要么失败)
### 回调
当一个方法的参数是一个函数时,那么这个函数就是这个方法的回调函数。
```javascript
function fn(cb){
// 模拟ajax
setTimeout(function(){
cb && cb()
},1000)
}
// 以回调嵌套回调的形式 一般称为回调地狱
// 回调执行一个依赖结果的方法时 代码会很冗余,不便于修改
fn(function(){
console.log('第一次请求')
fn(function(){
console.log('第二次请求')
fn(function(){
console.log('第三次请求')
})
})
})
```
### promise实例
将上例代码改为promise
```javascript
function fn(){
// promise的第一个参数 resolve
return new Promise((resolve)=>{
setTimeout(function(){
resolve()
},1000)
})
}
fn().then(function(){
// 这个方法就是promise实例中对应的resolve方法 也可以理解成是fn方法的回调
// 还可以继续返回promise实例
return fn()
}).then()
// ....
```
### promise错误处理
```javascript
function fn(flag){
// promise中接收第二个参数 reject 代表失败时的操作
return new Promise((resolve,reject)=>{
if(flag){
// ajax请求成功执行
resolve()
}else{
// ajax请求失败执行
reject()
}
})
}
// 用法1:
fn()
// 在then方法中传入第二个方法 就是对应的reject
.then(function(){},function(){})
// 用法2:
fn()
.then()
.catch(function(){
// catch中执行的方法就是reject方法
})
.finally(function(){
// 最终结果 无论成功与否都会执行 且不影响then/catch
})
```
### promise.all()
```javascript
// promise.all 将多个promise实例组成一个新的promise 接收一个数组 数组的每一项就是一个promise实例
// promise.all 数组中所有的promise返回结果都成功是 all方法就成功,当数组中有一个是失败时,all方法就失败
function getData1(f1){
return new Promise((resolve,reject)=>{
setTimeout(function(){
if(f1){
console.log('这是getData1')
resolve()
}else{
reject()
}
},500)
})
}
function getData2(f2){
return new Promise((resolve,reject)=>{
setTimeout(function(){
if(f2){
console.log('这是getData2')
resolve()
}else{
reject()
}
},1000)
})
}
function getData3(f3){
return new Promise((resolve,reject)=>{
setTimeout(function(){
if(f3){
console.log('这是getData3')
resolve()
}else{
reject()
}
},200)
})
}
Promise.all([getData1(true),getData2(false),getData3(true)])
.then(function(){
console.log('成功')
}).catch(function(){
console.log('失败')
}).finally(function(){
console.log('最终结果')
})
```
### promise.race()
```javascript
// promise.race 将多个promise实例组成一个新的promise 接收一个数组 数组的每一项就是一个promise实例
// promise.race 的执行结果 受第一个执行的promise实例影响 第一个promise返回成功 race方法就成功,否则相反
function getData1(f1){
return new Promise((resolve,reject)=>{
setTimeout(function(){
if(f1){
console.log('这是getData1')
resolve()
}else{
reject()
}
},500)
})
}
function getData2(f2){
return new Promise((resolve,reject)=>{
setTimeout(function(){
if(f2){
console.log('这是getData2')
resolve()
}else{
reject()
}
},1000)
})
}
function getData3(f3){
return new Promise((resolve,reject)=>{
setTimeout(function(){
if(f3){
console.log('这是getData3')
resolve()
}else{
reject()
}
},200)
})
}
Promise.race([getData1(true),getData2(false),getData3(true)])
.then(function(){
console.log('成功')
}).catch(function(){
console.log('失败')
}).finally(function(){
console.log('最终结果')
})
```
## class类
```javascript
// 通过class关键字定义一个类
class Car{
// constructor 是类的构造函数 钩子 会在实例化的时候自动执行
constructor(name,age){
this.name = name
this.age = age
}
}
// 通过new关键字 创建一个对象
let car1 = new Car("张三",18);// 类接收的参数 就会执行到constructor方法上
```
### 静态属性&方法
```javascript
// 静态属性和方法 static 静态属性和方法 只能类自身去调用
class Car{
static total = 0;
constructor(color){
this.color = color
Car.total += 1
Car.repair()
}
static repair(){
console.log('我是静态方法')
}
}
```
### getter和setter
在调用类中的属性是会触发getter方法,在修改类中的属性时会触发setter方法
```javascript
class Human{
name="张三"
say(){
console.log('我叫'+this.name)
}
set age(val){
console.log('age被修改成了:'+val)
}
get age(){
console.log('age被访问了')
}
}
let zs = new Human();
zs.age = 5 // 会触发 set age()方法 其中形参 val 就是被修改后的值
console.log(zs.age) // 会触发 get age()方法
```
### 类的继承
使用extends继承一个类
```javascript
// 定义一个父类
class Human{
constructor(name,age,sex,hobby){
this.name = name
this.sex = sex
this.age = age
this.hobby = hobby
}
say(){
let {name,age,sex,hobby} = this
console.log(`我叫${name},今年${age}岁,我是${sex}的,我喜欢${hobby.join('和')}`)
}
}
let xiaoming = new Human('小明',18,'男',['吃饭','睡觉','打豆豆'])
xiaoming.say()
// 定义一个子类
// extends 继承
class son extends Human{
constructor(name,age,sex,hobby,skill){
super(name,age,sex,hobby)// super方法用于传递父类的参数
this.skill = skill
}
say(){
let {name,age,sex,hobby,skill} = this
console.log(`我叫${name},今年${age}岁,我是${sex}的,我喜欢${hobby.join('和')},我会${skill}`)
}
}
let zs = new son('张三',16,'女',['唱','跳'],'vue') // 在子类中依然可以访问父类的属性和方法
zs.say() // 子类的方法和属性会覆盖父类的方法和属性
```