视频地址:【千锋前端JavaScript全套教程_JS零基础完美入门到项目实战】 https://www.bilibili.com/video/BV1W54y1J7Ed/?share_source=copy_web&vd_source=b1cb921b73fe3808550eaf2224d1c155
目录
13 ES6语法
ES6,ECMAScript的第6个版本,官方是ECMAScript2015.
13.1 定义变量
- ES6以前,定义变量使用 var 关键字
- ES6新增了两个定义变量的关键字
- let 定义变量
- const 定义常量
- let/const 与 var 的区别
- var 可以进行预解析
- let/const 不能进行预解析
- var 可以声明两个重名的变量
- let/const 不能定义重名变量
- var 没有块级作用域
- let/const 有块级作用域
- var 可以进行预解析
13.1.1 let/const 与 var 的区别
13.1.1.1 预解析
var可以进行预解析
// 1、预解析
console.log(num)
var num = 100
console.log(num)
运行结果
undefined
100
说明在打印num之前,num已经定义好了,只是没有赋值。这就是预解析。
let 和const不能预解析
不能在初始化之前使用num变量,定义之前使用 let/const 声明的变量会报错
console.log(num)
let num = 100
console.log(num)
13.1.1.2 重复变量
var 可以声明重复变量
// 2 重复变量名
var num1 = 100
var num1 = 200
console.log(num1)
结果num就是200
只有第二次的赋值有意义,第二次的声明没有意义。
let/const 不能声明重复变量
在vs code中就已经报错了。
13.1.1.3 块级作用域
什么是块级作用域:任何一个可以执行代码段的 {} 都会限制该变量的使用范围。
var 没有块级作用域
// 3 块级作用域
if(true) {
var num = 100
console.log(num)
}
console.log(num)
结果 100 100
let/const 有块级作用域
if(true) {
let num = 100
console.log(num)
}
console.log(num)
第二个打印没有正常执行。因为num在使用let定义,因此只能在 if 的 {} 内使用。
13.1.2 let 与 const 的区别
- let 定义变量的时候可以不赋值
- const 定义变量的时候必须赋值
- let 定义的变量可以被修改
- const 定义的变量一经赋值不能被修改
13.2 箭头函数
- 箭头函数,就是ES6语法中对 函数表达式 的简写
- 对 声明式函数 不能使用
- 在某些规则上又和以前的函数有些不同之处
13.2.1 什么是函数表达式
- 函数表达式,又叫做匿名函数
- 不需要单独定义函数,直接把函数赋值给什么
函数表达式实例
13.2.2 箭头函数
箭头函数是什么呢,即在书写函数表达式的时候, 省略掉 function 关键字,然后在 () 和 {} 之间加 箭头=>, 如下所示。
实例
var fn1 = function () {
console.log('我是 fn1 函数')
}
var fn2 = () => {
console.log('我是 fn2 函数')
}
fn1()
fn2()
13.2.3 箭头函数的特殊之处
- 箭头函数 某些时候可以省略 ()
- 当形参只有1个的时候,可以省略 ()
// 没有形参 var fn1 = () => { console.log('我没有形参') } fn1() // 有一个形参 var fn2 = a => { console.log('我有一个形参', a) } fn2(100) // 有2个形参 var fn3 = (a, b) => { console.log('我有2个形参', a , b) } // 这里不能省略 fn3(10,10)
- 当形参只有1个的时候,可以省略 ()
- 箭头函数某些时候可以省略 {}
- 当代码只有一句话的时候,可以不写 {}
- 并且会自动把这一句话的结果当做 函数的返回值
var fn1 = (a, b) => a + b console.log((100, 20))
结果120
- 箭头函数内没有 arguements
var fn2 = function() {console.log(arguments)} fn2(100,200,200) // 有arguments var fn1 = () => {console.log(arguments)} fn1(100,200,200) // 没有arguments,会报错
- 箭头函数里没有this
- 箭头函数内的 this 就是外部作用域的 this
var obj = { fn: function () {console.log(this)}, fn2: () => {console.log(this)} } obj.fn() // this 因为fn函数被obj调用,所以这里的this就是obj obj.fn2() // 因为是箭头函数,所以内部没有 this, //那么这里的this就是外部作用域的this, //这里的外部作用域就是全局, //打印出来就是window
打印结果
- 箭头函数内的 this 就是外部作用域的 this
13.3 函数参数默认值
- 函数在定义的时候,可以直接给 形参 设置一个 默认值
- 当没有传递 实参 的时候,就使用默认值
- 当传递了 实参,就使用传递的 实参
- 普通函数 可以使用,箭头函数 也可以使用
如果有两个形参,只传了一个实参,那么这个实参对应第一个形参,第二个形参依旧使用设置的默认值。
13.4 解构赋值
- 解构赋值:快速从 对象 或者 数组 中获取成员
- 分为 数组 的解构赋值 和 对象的解构赋值
13.4.1 数组的解构赋值
- 快速从 数组 中获取数据
- 注意:解构数组使用 ()
// 1. 解构数组
var arr = ['hello', 'world']
// 开始解构
// 注意:解构数组使用[]
// a 获取的就是 arr[0]
// b 获取的就是 arr[1]
var [a, b] = arr
console.log(a)
console.log(b)
13.4.2 对象的解构赋值
- 解构赋值-解构对象:快速从 对象 中获取数据
- 注意:解构对象使用 {}
示例
解构对象中 已经定义的成员
let obj = {
name: 'zyy',
age: 18
}
let{name, age} = obj
console.log(name)
console.log(age)
name 获得的是obj name成员的值
解构一个没有的成员
let{a} = obj
console.log(a)
结果是 undefined(没有这个成员)
给解构出来的对象成员起别名
定义一个 a 变量,从 obj 中获取 age 的值
let{age: a} = obj
console.log(a)
let{age: a} = obj 等价于 let a = obj.age
13.5 模板字符串
- 模板字符串:ES6内新增的定义字符串的方式。
- 以前定义字符串:var str = '内容' or var str = "内容"
- 现在定义字符串:var str = `内容` 全引号(英文状态下tab上面的键)
- 与普通字符串的区别
- 1、内容一样,那么与其他普通字符串一样
- 2、可以换行书写
- 3、可以在字符串内直接解析变量
- 与普通字符串的区别
- 1、内容一样,那么与其他普通字符串一样
var str = 'hello world'
var str2 = "hello world"
var str3 = `hello world`
console.log(str == str2)
console.log(str3 == str2)
console.log(str3 == str)
console.log(str3)
结果
- 与普通字符串的区别
- 2、可以换行书写
var str = 'hello world'
var str2 = "hello world"
var str3 = `
hello
world
`
且打印出来的效果与书写效果一致
- 与普通字符串的区别
- 3、可以在字符串内直接解析变量,其他普通变量不可解析
- 需要解析变量的时候,直接书写 ${ 变量 }
- 省去字符串拼接的问题
- 3、可以在字符串内直接解析变量,其他普通变量不可解析
var age = 18
var s1 = `我叫zyy, 今年${age}`
console.log(s1)
运行结果
13.6 展开运算符
- 展开运算符:...
- 作用:展开数组的 [ ] 或者展开对象的 { }
- 作用
- 1、合并数组
- 2、给函数传递参数
13.6.1 展开数组
var arr = [100, 200, 300, 400]
console.log(arr)
console.log(...arr)
// 相当于 console.log(100, 200, 300, 400)
// 即...将arr的[]去掉
作用:1、合并数组
var arr1 = [12, 2, 3]
var arr2 = [10, 20]
var arr3 = [19, 20]
var arr4 = [...arr1, ...arr2, ...arr3]
作用:2、给函数传递参数
var arr1 = [12, 2, 3]
var max = Math.max(...arr1)
console.log(max)
注意:max() 不能直接传入数组
13.6.2 展开对象
var obj = {name: 'zyy', age: 18}
console.log(obj)
console.log(...obj) // 会报错
不方便打印
- 作用
- 1、复制对象 注意:展开书写的顺序,在有相同成员的时候,注意顺序问题
var obj = {name: 'zyy', age: 18} // 作用1 复制对象 var obj2 = { gender: '男', ...obj }
- 1、复制对象 注意:展开书写的顺序,在有相同成员的时候,注意顺序问题
13.7 类语法
- ES6的类语法:用ES6的语法书写 构造函数
13.7.1 ES5构造函数缺点
缺点1:构造函数本质还是一个 函数, 只要是函数,就可以不和 new 关键字连用
但是不跟new连用,就创建不了对象,这就是缺点1。
function Person(name, age) {
this.name = name
this.age = age
}
// 给原型添加一个方法
Person.prototype.sayHi = function () {
console.log('sayHi')
}
var p1 = new Person('zyy', 18)
// 构造函数存在的问题
// 1、构造函数本质还是一个 函数, 只要是函数,就可以不和 new 关键字连用
var p2 = Person('zyy', 19)
// p2是undefined
缺点2:原型上的方法,目的是为了给实例使用。
即原型上的方法,应该跟构造函数是一体的。但是学的都是分开写的,这样不是错,只是不好。
所以ES6出现了类语法。
13.7.2 类语法
类语法的语法:
class 类名 {
// ES5 内的构造函数体
constructor () { }
// 直接书写原型上的方法即可
}
举例
// 类的书写
class Person {
constructor (name, age) {
this.name = name
this.age = age
}
sayHi () {
console.log('hello')
}
}
// 用法与ES5一样
var p1 = new Person('zyy', 18)
p1.sayHi()
Person 不和 new连用的时候会报错,因此,class 必须要和new关键字连用。
13.7.3 静态属性和方法
ES5构造函数使用静态属性和方法
function Person(name, age) {
this.name = name
this.age = age
}
// 给原型添加一个方法
Person.prototype.sayHi = function () {
console.log('sayHi')
}
// 书写静态属性和方法
Person.a = 100
Person.go = function () {
console.log('go!')
}
// 使用静态属性和方法
console.log(Person.a)
Person.go()
类里书写静态属性和方法,需要加上 static 关键字。
// 类的书写
class Person {
constructor (name, age) {
this.name = name
this.age = age
}
sayHi () {
console.log('hello')
}
// 静态属性
static a = 1000
// 静态方法
static go () {
console.log('go')
}
}
// 用法与ES5一样
var p1 = new Person('zyy', 18)
p1.sayHi()
// 使用静态属性和方法
console.log(Person.a)
Person.go()
其实类就是构造函数的ES6写法。