1. 初识ES6
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
-
1997年:ECMAScript 1.0
-
1998年:ECMAScript 2.0
-
1999年:ECMAScript 3.0
-
2006年:ECMAScript 4.0 未通过
-
2009年:ECMAScript 5.0
-
2015年:ECMAScript 6.0
-
至今,版本号改用年号的形式。
2. let声明变量与const声明变量
1. 相同的声明规则
let
不允许重复声明变量
// 使用 var 的时候重复声明变量是没问题的,只不过就是后面会把前面覆盖掉
var num = 100
var num = 200
// 使用 let 重复声明变量的时候就会报错了
let num = 100
let num = 200 // 这里就会报错了
// 使用 const 重复声明变量的时候就会报错
const num = 100
const num = 200 // 这里就会报错了
let
和const
声明变量不会在预解析的时候解析(也就是没有变量提升)
// 因为预解析(变量提升)的原因,在前面是有这个变量的,只不过没有赋值
console.log(num) // undefined
var num = 100
// 因为 let 不会进行预解析(变量提升),所以直接报错了
console.log(num)
let num = 100
// 因为 const 不会进行预解析(变量提升),所以直接报错了
console.log(num)
const num = 100
let
和const
声明的变量会被所有代码块限制作用范围
// var 声明的变量只有函数能限制其作用域,其他的不能限制
if (true) {
var num = 100
}
console.log(num) // 100
// let 声明的变量,除了函数可以限制,所有的代码块都可以限制其作用域(if/while/for/...)
if (true) {
let num = 100
console.log(num) // 100
}
console.log(num) // 报错
// const 声明的变量,除了函数可以限制,所有的代码块都可以限制其作用域(if/while/for/...)
if (true) {
const num = 100
console.log(num) // 100
}
console.log(num) // 报错
2. let
和const
的区别
let
声明的变量值可以改变,const
声明的变量值不可以改变
let num = 100
num = 200
console.log(num) // 200
const num = 100
num = 200 // 这里就会报错了,因为 const 声明的变量值不可以改变(我们也叫做常量) Assignment to constant variable.
let
声明的时候可以不赋值,const
声明的时候必须赋值
let num
num = 100
console.log(num) // 100
const num // 这里就会报错了,因为 const 声明的时候必须赋值
3. 解构赋值
解构赋值,就是快速的从对象或者数组中取出成员的一个语法方式
1. 解构对象
快速的从对象中获取成员
// ES5 的方法向得到对象中的成员
const obj = {
name: 'zhangsan',
age: 100,
gender: '男'
}
let name = obj.name
let age = obj.age
let gender = obj.gender
// 解构赋值的方式从对象中获取成员
const obj = {
name: 'zhangsan',
age: 100,
gender: '男'
}
// 前面的 {} 表示我要从 obj 这个对象中获取成员了
// name age gender 都得是 obj 中有的成员
// obj 必须是一个对象
let { name, age, gender } = obj
2. 解构数组
快速的从数组中获取成员
// ES5 的方式从数组中获取成员
const arr = ['zs', 'lisi', 'wangwu']
let a = arr[0]
let b = arr[1]
let c = arr[2]
// 使用解构赋值的方式从数组中获取成员
let arr = ['zs','ls','ww']
// 前面的 [] 表示要从 arr 这个数组中获取成员了
// a b c 分别对应这数组中的索引 0 1 2
// arr 必须是一个数组
let [a,a2,c] = arr
4. 模板字符串
ES5 中我们表示字符串的时候使用
''
或者""
在 ES6 中,我们还有一个东西可以表示字符串,就是 ``(反引号)
let str = `hello world`
console.log(typeof str) // string
和单引号和双引号的区别
-
反引号可以换行书写
// 这个单引号或者双引号不能换行,换行就会报错了 let str = 'hello world' // 下面这个就报错了 let str2 = 'hello world'
let str = ` hello world ` console.log(str) // 是可以使用的
-
反引号可以直接在字符串里面拼接变量
// ES5 需要字符串拼接变量的时候
let num = 100
let str = 'hello' + num + 'world' + num
console.log(str) // hello100world100
// 直接写在字符串里面不好使
let str2 = 'hellonumworldnum'
console.log(str2) // hellonumworldnum
// 模版字符串拼接变量
let num = 100
let str = `hello${num}world${num}`
console.log(str) // hello100world100
在 `` 里面的
${}
就是用来书写变量的位置
5. 字符串扩展
includes
函数
判断字符串中是否存在指定字符
let myname = "zhangsan"
console.log(myname.includes("a")) //true
console.log(myname.startsWith("z")) //true
console.log(myname.endsWith("n")) //true
repeat
函数
repeat()
方法返回一个新字符串,表示将原字符串重复n次。
et myname = "zhangsan"
console.log(myname.repeat(3)) //zhangsanzhangsanzhangsan
console.log(myname.repeat(0)) //""
console.log(myname.repeat(3.5)) //zhangsanzhangsanzhangsan
console.log(myname.repeat("3"))//zhangsanzhangsanzhangsa
6. 数值扩展
- 二进制和八进制表示法
let count1 = 100
let count2 = 0x100
let count3 = 0o100
let count4 = 0b100
isFinite
与isNaN
方法
减少全局性方法,使得语言逐步模块化
let num1 = Number.isFinite(100) //true
let num2 = Number.isFinite(100/0) //false
let num3 = Number.isFinite(Infinity) // false
let num4 = Number.isFinite("100") //false
let num1 = Number.isNaN(100) // false
let num2 = Number.isNaN(NaN) //true
let num3 = Number.isNaN("kerwin") //false
let num4 = Number.isNaN("100") // false
它们与传统的全局方法isFinite()和isNaN()的区别在于,传统方法先调用Number()将非数值的值转为数值,再进行判断,而这两个新方法只对数值有效,Number.isFinite()对于非数值一律返回false, Number.isNaN()只有对于NaN才返回true,非NaN一律返回false。
isInteger
方法
用来判断一个数值是否为整数。
let num1 = Number.isInteger(100) // true
let num2 = Number.isInteger(100.0) //true
let num3 = Number.isInteger("kerwin") //false
let num4 = Number.isInteger("100") // false
- 极小常量
Number.EPSILON
它表示 1 与大于 1 的最小浮点数之间的差。2.220446049250313e-16
function isEqual(a,b){
return Math.abs(a-b)<Number.EPSILON
}
console.log(isEqual(0.1+0.2,0.3)) //true
console.log(0.1+0.2===0.3) //false
Math.trunc
将小数部分抹掉,返回一个整数。
console.log(Math.trunc(1.2)) //1
console.log(Math.trunc(1.8))// 1
console.log(Math.trunc(-1.8)) //-1
console.log(Math.trunc(-1.2))//-1
Math.sign
Math.sign
方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
Math.sign(-100) // -1
Math.sign(100) // +1
Math.sign(0) // +0
Math.sign(-0) // -0
Math.sign("kerwin") // NaN
7. 数组扩展
- 扩展运算符
...
let arr1 = [1,2,3]
let arr2 = [4,5,6]
console.log([...arr1,...arr2]) // [1,2,3,4,5,6]
Array.from
将类数组对象(Iterator)转换为真正数组
function test(){
//arguments 函数内默认自带的参数
console.log(Array.from(arguments))
}
test(1,2,3)
let oli = document.querySelectorAll("li")
console.log(Array.from(oli))
Array.of
将一组值转化为数组,即新建数组
let arr1 = Array(3)
console.log(arr1)// [,,] 创建了一个长度为3的数组
let arr2 = Array.of(3)
console.log(arr2)// [3]
find
方法
- 该方法主要应用于查找第一个符合条件的数组元素
- 它的参数是一个回调函数。在回调函数中可以写你要查找元素的条件,当条件成立为true时,返回该元素。如果没有符合条件的元素,返回值为undefined
let arr = [11,12,13,14,15]
let res1 = arr.find(function(item){
return item>13
})
let res2 = arr.findIndex(function(item){
return item>13
})
console.log(res1) //14
console.log(res2) //3
fill
方法
使用自己想要的参数替换原数组内容,但是会改变原来的数组
let arr1 = new Array(3).fill("zs")
let arr2 = ['a', 'b', 'c'].fill("zs", 1, 2)//从1索引位置开始,2结束
console.log(arr1)//['zs', 'zs', 'zs']
console.log(arr2)// ['a', 'zs', 'c']
flat
与flatMap
方法
按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回
flat 直接展开,flatMap按照回调返回结果依次展开
let arr = ["鞍山", "安庆", "安阳"]
console.log(arr.flat())
var obj = [{
name: "A",
list: ["鞍山", "安庆", "安阳"]
},
{
name: "B",
list: ["北京", "保定", "包头"]
}
]
console.log(obj.flatMap(item => item.list))
8. 对象扩展
- 对象简写
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。
对象中可以直接写函数-省略了function 声明。
let name ="moduleA"
let obj = {
name,
test1(){
},
test2(){
}
}
- 属性名表达式
[属性名]
let name ="moduleA"
let obj = {
name,
[name+"test1"](){
},
[name+"test2"](){
}
}
Object.assign
用于对象的合并,将源对象所有可枚举的属性,复制到目标对象上。
Object.assign(target, object1,object2...)
的第一个参数是目标对象,后面可以跟一个或多个源对象作为参数。
target:参数合并后存放的对象
object1:参数1
object2:参数2
const obj1 = {
name: "kerwin"
};
const obj2 = {
name:"tiechui"//当目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
};
const obj3 = {
age:100
};
Object.assign(obj1, obj2, obj3);
//obj1 {name: 'tiechui', age: 100}
Object.is
用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。(但Object.is可以比较NaN)
console.log(NaN===NaN) //false
console.log(+0===-0) //true
console.log(Object.is(NaN,NaN)) //true
console.log(Object.is(+0,-0)) //false
9. 函数扩展
- 箭头函数
箭头函数是 ES6 里面一个简写函数的语法方式
重点: 箭头函数只能简写函数表达式,不能简写声明式函数
function fn() {} // 不能简写
const fun = function () {} // 可以简写
const obj = {
fn: function () {} // 可以简写
}
语法:
(函数的行参) => { 函数体内要执行的代码 }
const fn = function (a, b) {
console.log(a)
console.log(b)
}
// 可以使用箭头函数写成
const fun = (a, b) => {
console.log(a)
console.log(b)
}
const obj = {
fn: function (a, b) {
console.log(a)
console.log(b)
}
}
// 可以使用箭头函数写成
const obj2 = {
fn: (a, b) => {
console.log(a)
console.log(b)
}
}
- 箭头函数的特殊性
- 箭头函数内部没有 this,箭头函数的 this 是上下文的 this
// 在箭头函数定义的位置往上数,这一行是可以打印出 this 的
// 因为这里的 this 是 window
// 所以箭头函数内部的 this 就是 window
const obj = {
fn: function () {
console.log(this)
},
// 这个位置是箭头函数的上一行,但是不能打印出 this
fun: () => {
// 箭头函数内部的 this 是书写箭头函数的上一行一个可以打印出 this 的位置
console.log(this)
}
}
obj.fn()
obj.fun()
按照我们之前的 this 指向来判断,两个都应该指向 obj
但是 fun 因为是箭头函数,所以 this 不指向 obj,而是指向 fun 的外层,就是 window
- 箭头函数内部没有
arguments
这个参数集合
const obj = {
fn: function () {
console.log(arguments)
},
fun: () => {
console.log(arguments)
}
}
obj.fn(1, 2, 3) // 会打印一个伪数组 [1, 2, 3]
obj.fun(1, 2, 3) // 会直接报错 arguments is not defined
- 函数的行参只有一个的时候可以不写
()
其余情况必须写
const obj = {
fn: () => {
console.log('没有参数,必须写小括号')
},
fn2: a => {
console.log('一个行参,可以不写小括号')
},
fn3: (a, b) => {
console.log('两个或两个以上参数,必须写小括号')
}
}
- 函数体只有一行代码的时候,可以不写
{}
,并且会自动 return
const obj = {
fn: a => {
return a + 10
},
fun: a => a + 10
}
console.log(fn(10)) // 20
console.log(fun(10)) // 20
- 函数传递参数的时候的默认值
我们在定义函数的时候,有的时候需要一个默认值出现
就是当我不传递参数的时候,使用默认值,传递参数了就使用传递的参数
//ES5
function fn(a) {
a = a || 10
console.log(a)
}
fn() // 不传递参数的时候,函数内部的 a 就是 10
fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
在 ES6 中我们可以直接把默认值写在函数的行参位置
这个默认值的方式箭头函数也可以使用
function fn(a = 10) {
console.log(a)
}
fn() // 不传递参数的时候,函数内部的 a 就是 10
fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
const fn = (a = 10) => {
console.log(a)
}
fn() // 不传递参数的时候,函数内部的 a 就是 10
fn(20) // 传递了参数 20 的时候,函数内部的 a 就是 20
注意: 箭头函数如果你需要使用默认值的话,那么一个参数的时候也需要写 ()