今天起复习ES6-ES10的新知识,为以后做准备。
1.let
1.1 let声明的变量不会挂载到window上
var a = 3
let b = 4
console.log(a, b) // 3 4
console.log(window.a, window.b) // 3 undefined
1.2 let不能重复声明变量
// 可行
var a = 3
var a = 4
// 报错
let b = 4
let b = 5
1.3 let不存在变量提升
2.const
2.1 const声明的变量不会挂载到window上
2.2 const不能重复声明变量
2.3 const不存在变量提升
2.4 const声明的常量不能重新赋值
// 报错
const a = 1
a = 2
// 报错 const声明必须赋值
const b
b = 1
3.遍历
3.1 es5中遍历的方法
3.1.1 for循环
let arr = [1, 2, 3, 4]
for (let i = 0; i < arr.length; i++) {
console.log(arr[i])
}
3.1.2 forEach
let arr = [1, 2, 3, 4]
arr.forEach((item) => {
console.log(item)
})
forEach问题,不能continue和break,如果想终止循环可以通过抛出异常
let arr = [1, 2, 3, 4]
try {
arr.forEach((item) => {
if (item === 2) {
throw new Error('')
}
console.log(item)
})
} catch (e) {
console.log('循环结束')
}
3.1.3 every
every也可以遍历,也不支持continue和break,但是可以通过return false
终止循环(默认返回false)
let arr = [1, 2, 3, 4]
arr.every((item) => {
if (item === 3) {
return false
}
console.log(item)
return true
})
3.1.4 for...in(为对象设计的)
支持continue和break
let arr = [1, 2, 3, 4]
for (let index in arr) {
console.log(index, arr[index])
}
由于数组是对象,所以可以给数组新增属性,给数组新增属性之后,for...in可以把a也遍历出来,这是一个瑕疵。 而且循环时我们定义的index是字符串。
let arr = [1, 2, 3, 4]
arr.a = 8
for (let index in arr) {
console.log(index, arr[index]) // 会把a和8打印出来
}
for...in遍历对象需要配合hasOwnProperty
使用
let obj = {
a: 1,
b: 2
}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(obj[key])
}
}
3.2 es6中的遍历方法
3.2.1 for...of
for...of可以遍历任何可遍历的数据结构
for (let item of arr) {
console.log(item)
}
4.Array
4.1 Array.from
涉及到的问题是如何把伪数组转换成数组
NodeList(选中的DOM集合)
arguments(函数参数集合)
他们在特性上像数组,但是不能直接使用数组的方法。
伪数组有两个特征,第一个特征是按照索引储存属性,第二个特征是有length属性
// 这就是个伪数组
{
0: 'a',
1: 'b',
length: 2
}
4.1.1 es5方法
let args = Array.prototype.slice.call(arguments)
let imgs = Array.prototype.slice.call(document.querySelectorAll('img'))
4.1.2 es6方法
let args = Array.from(arguments)
let imgs = Array.from(document.querySelectorAll('img'))
4.1.3 Array.from详解
Array.from(arrayLike, mapFn, thisArg)
第一个参数是需要转换的伪数组,第二个参数是一个函数,每次遍历都会执行,第三个参数是this指向
let arr = Array.from({length: 5}, function () {return 1}, null)
4.2 Array.of
把几个元素放到数组中,不需要像以前每个都push
let array = Array.of(1, 2, 3, 4, 5) // [1, 2, 3, 4, 5]
4.3 Array.fill
4.3.1 填充数组
let array = Array(5).fill(1) // [1, 1, 1, 1, 1]
4.3.2 fill参数
Array.fill(value, start, end) // 包括start不包括end
4.4 查找数组
4.4.1 es5中在数组中找到某一项
数组遍历完才停止,所以会把符合条件的值都找到
let arr = [1, 2, 3, 4]
let find = arr.filter((item) => {
return item === 3
})
console.log(find) // [3]
let find2 = arr.filter((item) => {
return item === 6
})
console.log(find2) // []
let find3 = arr.filter((item) => {
return item % 2 === 0
})
console.log(find3) // [2, 4]
缺点是,如果数组非常大,我们在数组中寻找某一项的话,filter会把数组遍历完
4.4.2 es6中的find
找到第一个符合条件的就停止
let arr = [1, 2, 3, 4]
let find = arr.find((item) => {
return item === 3
})
console.log(find) // 3
let find2 = arr.find((item) => {
return item === 6
})
console.log(find2) // undefined
let find3 = arr.find((item) => {
return item % 2 === 0
})
console.log(find3) // 2
4.4.3 es6中的findIndex
let arr = [1, 2, 3, 4]
let find = arr.findIndex((item) => {
return item === 3
})
console.log(find) // 2
5.类
5.1 ES5中的类
let Animal = function (type) {
this.type = type
}
Animal.prototype.eat = function () {
console.log('eat')
}
let cat = new Animal('cat')
let dog = new Animal('dog')
5.2 ES6中的类
ES5类的语法糖
class Animal {
constructor (type) {
this.type = type
}
eat () {
console.log('eat')
}
}
let cat = new Animal('cat')
let dog = new Animal('dog')
5.3 属性读写(getter setter)
getter
let _age = 4
class Animal {
constructor (type) {
this.type = type
}
get age () {
return _age
}
eat () {
console.log('eat')
}
}
let dog = new Animal('dog')
console.log(dog.age) // 4
dog.age = 11
console.log(dog.age) // 4
setter
let _age = 4
class Animal {
constructor (type) {
this.type = type
}
get age () {
return _age
}
set age (val) {
if (val > 4 && val < 7) {
_age = val
}
}
eat () {
console.log('eat')
}
}
let dog = new Animal('dog')
console.log(dog.age) // 4
dog.age = 11
console.log(dog.age) // 4
dog.age = 6
console.log(dog.age) // 6
目的是控制一个属性只读,或者是有条件的更改
5.4 操作方法(静态方法)
class Animal {
constructor (type) {
this.type = type
}
eat () {
Animal.walk() // 静态方法必须用类调用
console.log('eat')
}
static walk () {
console.log('walk')
}
}
let dog = new Animal('dog')
dog.eat() // walk eat
dog.walk() // dog.walk is not a function
eat是实例对象的方法
walk是静态方法
如果方法依赖于实例对象的属性,就用实例对象方法。没有依赖就用静态方法,静态方法是拿不到实例对象中的属性的。
5.5 继承
ES5中,继承的步骤是:(不止这一种实现方法) (1)在子类中执行一遍父类的构造函数 (2)将子类原型指向父类
function Animal (type) {
this.type = type
}
Animal.prototype.eat = function () {
console.log('eat')
}
function Dog () {
Animal.call(this, 'dog')
this.run = function () {
console.log('run')
}
}
Dog.prototype = Animal.prototype
ES6中继承:也要先执行父类的构造函数(子类构造函数如果是空的,可以省略constructor),super()必须放在构造函数第一行。
class Animal {
constructor (type) {
this.type = type
}
eat () {
Animal.walk() // 静态方法必须用类调用
console.log('eat')
}
}
class Dog extends Animal {
constructor (type) {
super(type)
this.age = 2
}
}