ES6新特性全总结

ES6的新特性总结

1、用let声明变量

1.2let声明的变量不允许重复声明
let movie = 'Lord of the Rings'
var movie = 'Batman v Superman' // SyntaxError: Identifier 'movie' has already been declared
1.3 let声明的变量存在块级作用域
var num1 = 10
if(num1 === 10){
	var num2 = 20	
}
console.log(num2) // 20

--------------------------------------------
let num1 = 10
if(num1 === 10){
    let num2 = 20
}
console.log(num2) // ReferenceError: num2 is not defined
// 上面代码中,使用var声明的变量不存在块级作用域,可以直接在全局中访问
// let声明的变量存在块级作用域,所谓的`块级作用域`,通俗地来讲可以理解为一对花括号{}就是一个块级作用域
// 在这个作用域内用let声明的变量存在块级作用域,只能在该作用域下才能访问
// 所以打印num2那一行代码在全局作用域下,根据作用域链的查找顺序,num2是无法被查找到的
// 所以报了这样一个错误`ReferenceError: num2 is not defined`
1.3 let声明的变量没有变量提升机制,存在暂时性死区
console.log(a) // undefined
var a = 10
console.log(b) // ReferenceError: Cannot access 'b' before initialization
let b = 10

以上代码中,第二行用var声明的变量有变量提升机制,第一行代码和第二行代码相当于

var a 
console.log(a) // undefined 声明了a但却没有赋值,所以打印undefined
a = 10 

第三行和第四行用let声明的变量则没有变量提升的机制,即我们不能在它初始化之前访问它,编译器会报一个引用类型的错误,在MDN文档中这一现象被称之为暂时性死区。用const声明的变量与let类似。

2、用const声明常量

2.1 const的基本说明

ES2015中还引入了const关键字,它的行为和let关键字一样,唯一的区别在于,用const定义的变量是只读的,也就是常量

2.2 const声明的值不允许修改,const是一个常量
const PI = 3.1415926
PI = 3.0 // TypeError: Assignment to constant variable.

以上代码会报一个类型错误,即尝试给常量或只读变量赋值,因为const声明的是一个常量,是不允许修改的。但是,以下情况会有所不同:

const jsFrameWork = {
	name: 'Vue'
}
jsFrameWork.name = 'React' 
console.log(jsFrameWork.name) // 正常输出 React

如果您尝试运行这段代码,它会正常地工作并且输出 React,但是前面已经说到const声明的变量是一个常量,是不允许修改的,那么这儿为什么可以正常执行呢?那就不得不说到js变量是如何在内存中存储的知识,当我们声明基础数据类型时,js会在栈内存中开辟一块空间,用于存储变量名和变量值;当我们声明引用数据类型时,会先在栈内存中开辟一块内存用于存储变量名和堆内存中的地址值,随后在堆内存中开辟一块空间用于存储其具体的值,并且将栈内存中的地址指向堆内存中具体的值的地址。

总结:对于非对象类型的变量,比如数值型、布尔类型、字符串类型,我们不可以改变const声明的变量的值,但是当我们遇到对象时,只读的const允许我们修改或重新赋值对象的属性,但变量本身的引用(指向堆内存中的引用地址)不可以修改,也就是不能对这个变量进行重新赋值。

如果您像下面这样尝试重新给jsFrameWork变量重新赋值,编译器就会抛出异常

const jsFrameWork = {
	name: 'Vue'
}
jsFrameWork = {
    name: 'React' 
} // TypeError: Assignment to constant variable.
2.3 const与let一样存在块级作用域
if(true){
	const num = 20
}
console.log(num) // ReferenceError: num is not defined 存在块级作用域,无法访问num变量
2.4 const初始化时必须赋值,否则会报错

如果声明了const变量却没有给变量赋值,则会抱一个语法错误:const声明缺少初始化值

const num
console.log(num) // SyntaxError: Missing initializer in const declaration
2.5 不成文的约定

当我们使用const 声明基础数据类型时,通常将变量名大写。

3、模板字面量

3.1 模板字面量的基本说明和使用

ES6的模板字面量又称模板字符串,模板字面量真的很棒,因为我们在创建字符串的时候不必再拼串,在需要换行的时候也不必使用转义字符

比如,以下代码中

const book = {
    name: '霍乱时期的爱情'
}
console.log('你正在阅读' + book.name + ',\n这是新的一行\n 这也是新的一行')

以上代码就是ES5和之前如果需要换行打印或者拼接字符串数据的语法,但是现在我们可以直接使用ES6提供的模板字面量的方法

const book = {
	name: '霍乱时期的爱情'
}
console.log(`你正在阅读${book.name},
	这是新的一行
	这也是新的一行
`)
3.2 模板字面量的语法

模板字面量使用反引号 ``作为标志(使用一对反引号包裹),在反引号内部可以使用${}访问其能够访问到的作用域下的任何变量名,当然如上面的代码所示,模板字面量支持换行和空格显示。

4、箭头函数

4.1 箭头函数基础用法

ES6中的箭头函数极大地简化了普通函数的语法,方便了js开发者,但是很多地方仍然需要我们注意!

当我们有如下的例子:

var circleAreaES5 = function circleArea(r){
	var PI = 3.14
    var area = PI * r * r
    return area
}
console.log(circleAreaES5(10)) // 314
---- 以下为箭头函数写法 ----
const circleArea = (r) => {
    const PI = 3.14
    const area = PI * r * r
    return area
}
console.log(circleArea(10)) // 314

这个例子最大的区别在于我们可以省略掉function关键字,只使用=>

当只有一个参数时以及函数只有一条语句时,我们的写法还可以变得更简单,我们可以省略掉参数的括号以及函数体的花括号return关键字,如下

const PI = 3.14
const circleArea = r => PI * r * r
console.log(circleArea(10)) // 314
4.2 箭头函数的this指向

当说到箭头函数的this指向时,让我们先来总结一波普通函数的this指向:

let obj = {
    name: '艾向阳',
    sayHello: function(){
        console.log(`hello ${this.name}`)
    }
}

obj.sayHello() // 打印 hello 艾向阳

普通函数的this指向没有那么复杂,通常来说,谁调用函数this就指向谁。除此之外,定义在全局中的函数的this指向顶级对象,在非严格模式下 浏览器中的 函数this 指向window对象,nodejs中的函数this指向global。

另外,调用call、apply、bind会修改函数this的指向,会将函数的this指向call/apply/bind的第一个参数,示例代码如下:

let obj = {
    name: '艾向阳',
    sayHello: function(){
        console.log(`hello ${this.name}`)
    }
}

let obj2 = {
	name: '爱新觉罗'
}
obj.sayHello.call(obj2) // 打印hello 爱新觉罗

apply和bind的情况与此类似,只是他们传递参数和函数调用时机不同,这里不对call、apply、bind的区别做过多讲解,以后有时间会出一期三者的异同讲解和手写实现。

但在箭头函数中,this的指向就会有所不同,先总结一点:箭头函数没有自己的this,箭头函数的this是捕获其所在上下文的this值作为自己的this值,还是上面的例子:

let obj = {
    name: '艾向阳',
    sayHello: () => {
        console.log(`hello ${this.name}`)
    }
}

obj.sayHello() // 打印 hello undefined

很奇怪,当采用箭头函数的写法时,this并不指向函数的直接调用者,那么我们打印this,会发现this其实是指向它当前的上下文的this。除此之外,我们还可以通过Babel(ES6之后代码转ES5的一个方便的工具)来更加深刻的理解箭头函数中的this指向:

// ES6
const obj = {
	getArrow(){
		return () => {
			console.log(this === obj) // true
		}
	}
}

// ES5,由Babel转译
var obj = {
    getArrow: function getArrow(){
        var _this = this
        return function (){
            console.log(_this === obj) // true
        }
    }
}

5、ES6中对象增强

5.1 对象属性简写

在ES6中,当对象的key value变量名相同时,我们可以对对象进行简写,这也会大大提高开发效率和降低代码维护难度,示例如下

let name = '艾向阳'
const obj = {
    name: name
}
consle.log(obj) // {name: '艾向阳'}
// ES6对象简写
const obj2 = {
    name
}
// 打印obj2也会得到相同的结果 {name: '艾向阳'}

除了对象名和对象值可以简写,ES6允许我们在对象的属性中也可以对函数进行简写

const obj = {
    name: '艾向阳',
    sayHello: function sayHello(){
        consle.log(this.name) 
    }
}
obj.sayHello() // 艾向阳
// 简写形式
const obj2 = {
    name: '艾向阳',
    sayHello(){
        consle.log(this.name)
    }
}
obj2.sayHello() // 艾向阳

注意:只有当对象的key与函数名相同时才能采用简写形式!

5.2 解构赋值

ES6中引入了数组结构的概念,可以用来一次初始化多个变量

let [x,y] = ['a','b']

// 以上代码和下面的代码效果是相同的
let x = 'a'
let y = 'b'

对象也可以采用这种解构的写法,这是我工作中经常用到的写法

async getTableData(){
    try {
        const {data,rsCode} = await getTableDataApi()
    } catch(e){
        
    }
}

上述代码中getTableDataApi是一个封装好的ajax请求,服务器会固定地返回一个对象,其中包括data,rsCode等字段,此时我们就可以采用对象解构的写法。

6、函数的参数默认值与声明展开及剩余参数

6.1 函数的参数默认值

在ES6中,函数的参数还可以定义默认值。

function sum(x,y,z = 3){
    return x + y + z
}
sum(1,2) // 返回 6 

以上代码中,因为我们有没有传入参数z的值,所以采用它的默认值3,因此 1+2+3 = 6,在ES6之前上面的函数只能这样:

function sum(x,y,z){
    if(x === undefined) x = 1
    if(y === undefined) y = 2
    if(z === undefined) z = 3
    return x + y + z
}

在使用函数参数默认值时,需要注意:需要将设置了默认值的参数放在参数的最后,否则会出现错误,如下

function sum(x,z = 3,y){
    return x + y + z
}
sum(1,2) // NaN
6.2 声明展开与剩余参数

在ES5中我们可以使用apply函数将数组转化为参数,因此ES6有了展开运算符(…),以上面的sum函数为例,可以执行如下代码来传入参数x,y,z

let params = [1,2,3]
function sum(x,y,z){
    return x + y + z
}
sum(...params) // 6
// ES5写法
sum.apply(undefined,params) // 6

在函数中,展开运算符(…)也可以代替剩余参数arguments,当作剩余参数使用。

关于剩余参数的定义:JavaScript函数中有一个内置的对象,叫做arguments对象,它时一个类数组,包含函数调用时传入的参数,即使不知道参数的名称,我们也可以动态地通过arguments获取并使用这些参数

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值