抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

ES6新特性

let

  • 变量不能重复声明
  • 产生块级作用域
  • 不存在变量提升
  • 不影响作用域链

const

  • 声明常量,要赋初始值,不能重复声明
  • 产生块级作用域
  • 对数组或对象元素的修改,不算对常量的修改
  • 不存在变量提升
  • 不影响作用域链

作用域

  • 局部作用域

    • 函数作用域:函数内部声明的变量只能在函数内部访问
    • 块作用域:使用{}包裹的代码块内部声明的变量外部有可能无法访问
      • let和const产生块作用域
      • var不会产生块作用域
  • 全局作用域:<script>标签和js文件的最外层,声明的变量在其他任何作用域都能访问

    • window对象动态添加的属性也是全局的
    • 函数中未使用任何关键字声明的变量也是全局的
  • 作用域链:优先查找当前,依次查找父级作用域

变量和函数提升

代码执行前,所有var声明的变量被提升到当前作用域的最前面。只提升声明,不提升赋值。

代码执行前,所有函数声明被提升到当前作用域的最前面。

解构赋值

1
2
3
4
5
6
7
8
9
10
11
12
//数组解构赋值
const F4 = ['小沈阳','刘能','赵四','宋小宝'];
const [xiao,liu,zhao,song]= F4;
//对象解构赋值
const obj = {
name:'hzx',
age:18,
sayHello: function(){
console.log('hello');
}
}
const {name,age,sayHello} = obj;

模板字符串

箭头函数

rest参数

与arguments的区别

  • 语法:arguments是一个内置对象,而rest参数是通过…语法创建的。
  • 类型:arguments是一个类数组对象,而rest参数是一个真正的数组。
  • 位置:rest参数必须放在函数参数列表的最后面,而arguments对象在任何函数中都可用。
  • 功能:rest参数提供了一个数组,可以直接使用数组的方法,而arguments对象需要转换才能使用数组方法。

扩展运算符

...将数组转化为逗号分隔参数序列

Symbol

  • Symbol的值是唯一的,用来解决命名冲突问题
  • Symbol值不能与其他数据进行运算
  • Symbol定义的对象属性不能使用for in或for of循环遍历,但是可以使用Object.getOwnPropertySymbols() 和 Reflect.ownKeys()来获取对象的所有键名

迭代器

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
34
35
36
37
38
39
40
41
const banji = {
name:"终极一班",
students:[
'xiaoming',
'xiaoning',
'xiaotian',
'knight'
],
[Symbol.iterator](){
let index = 0;
return {
next:()=>{
if(index<this.students.length){
const res = {value:this.students[index],done:false}
index++
return res
}
return {value: undefined, done:true}
}
}
}
}
for(let v of banji){
console.log(v)
}
const iterator = banji[Symbol.iterator]()
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
//输出
xiaoming
xiaoning
xiaotian
knight
{value: 'xiaoming', done: false}done: false
{value: 'xiaoning', done: false}
{value: 'xiaotian', done: false}
{value: 'knight', done: false}
{value: undefined, done: true}

生成器

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 * generator(){
console.log('111')
yield '一只没有耳朵'
console.log('222')
yield '一只没有尾巴'
console.log('333')
yield '真奇怪'
console.log('444')
}
const iterator = generator()
for(let v of generator()){
console.log(v)
}
iterator.next()
iterator.next()
iterator.next()
iterator.next()
//输出
111
一只没有耳朵
222
一只没有尾巴
333
真奇怪
444
111
222
333
444

应用实例

  1. 解决回调地狱
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
34
35
36
37
//回调地狱
// setTimeout(() => {
// console.log('111')
// setTimeout(() => {
// console.log('222')
// setTimeout(() => {
// console.log('333')
// }, 3000)
// }, 2000)
// }, 1000)
//生成器函数解决回调地狱
function one(){
setTimeout(()=>{
console.log('111')
iterator.next()
},1000)

}
function two(){
setTimeout(()=>{
console.log('222')
iterator.next()
},2000)
}
function three(){
setTimeout(()=>{
console.log('333')
iterator.next()
},3000)
}
function * generator(){
yield one()
yield two()
yield three()
}
let iterator = generator()
iterator.next()
  1. 异步编程
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 getUsers(){
setTimeout(()=>{
let data = '用户数据'
iterator.next(data)
},1000)

}
function getOrders(){
setTimeout(()=>{
let data = '订单数据'
iterator.next(data)
},2000)
}
function getGoods(){
setTimeout(()=>{
let data = '商品数据'
iterator.next(data)
},3000)
}
function * generator(){
const users = yield getUsers()
console.log(users)
const orders = yield getOrders()
console.log(orders)
const goods = yield getGoods()
console.log(goods)
}
let iterator = generator()
iterator.next()

Promise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const fs = require("fs")
const p = new Promise((resolve,reject)=>{
fs.readFile('./静夜思.md',(err,data)=>{
resolve(data)
})
})

p.then(value=>{
return new Promise((resolve,reject)=>{
fs.readFile('./琵琶行.md',(err,data)=>{
resolve([...value,data])
})
})
}).then(value=>{
return new Promise((resolve,reject)=>{
fs.readFile('./滕王阁序.md',(err,data)=>{
resolve([...value,data])
})
})
}).then(value=>{
console.log(value.join('\n'))
}
)

Set

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const arr1 = [3,1,4,1,5,9,2,6]
const arr2 = [4,8,6,9]
const s2 = new Set(arr2)
//数组去重
let result = [...new Set(arr1)]
console.log(result)
//求交集
const intersection = [...new Set(arr1)].filter(item=>s2.has(item))
console.log(intersection)
//求并集
const union = [...new Set([...arr1,...arr2])]
console.log(union)
//求差集
const diff = [...new Set(arr1)].filter(item=>!s2.has(item))
console.log(diff)

class

构造函数执行过程

  1. 创建新对象
  2. 构造函数this指向新对象
  3. 执行构造函数代码,修改this,添加新的属性
  4. 返回新对象

原型对象

  • 每个构造函数都有一个prototype属性,指向原型对象
  • 这个对象可以挂载函数,对象实例化不会多次创建原型上的函数,节约内存
  • 构造函数通过原型分配的函数是所有对象所共享的,可以将不变的方法直接定义在prototype对象上,这样所有对象的实例就可以共享这些方法
  • 构造函数和原型对象中的this都指向实例化的对象

constructor

原型对象上的构造器,指向构造函数

对象原型

实例对象的__proto__属性,指向构造函数的原型对象

原型链

  1. 当访问一个对象的属性和方法时,首先查找这个对象自身有没有该属性。
  2. 如果没有就查找它的原型(就是__proto__指向的prototype原型对象。
  3. 如果还没有就继续查找原型对象的原型,直至查找到null
  4. 可以用 instanceof 运算符检测构造函数的prototype属性是否出现在某个实例对象的原型链上。

模块化

babel

babel是一个JavaScript编译器

1
npm i babel-cli babel-preset-env browserify -D
1
2
3
4
//代码转换
npx babel src/js -d dist/js --presets=babel-preset-env
//打包
npx browserify dist/app.js -o dist/bundle.js

async与await

作用:使异步代码看起来像同步代码一样

async函数

  • async函数的返回值为Promise对象
  • Promise对象的结果由async函数执行的返回值决定

await表达式

  • await必须写在async函数中
  • await右侧的表达式一般为Promise对象
  • await返回的是Promise成功的值
  • await的Promise失败了,就会抛出异常,需要try…catch捕获处理

动态导入

1
()=>import()

评论