目录
- 一、ES6的新特性
- 1、什么是ES6?
- 2、ES6和JavaScript的关系
- 3、相对于JavaScript新增加的特性
- 小练习
- 4、模板字符串
- 5、Symbol
一、ES6的新特性
1、什么是ES6?
ECMAScript 6.0(以下简称ES6)是Javascript语言的下一代标准,已经在2015年6月正式发布了。
2、ES6和JavaScript的关系
ECMAScript是Javascript的语法规定,JavaScript是ECMAScript的实现。
3、相对于JavaScript新增加的特性
(1)let和const:两种新的声明方式
A、JavaScript中var声明方式的局限:会造成变量的作用域提升。
var sum=0
for(var i=0;i<10;i++){ //用var来声明,提升了i的作用域
sum += i
}
console.log('sum=',sum)
console.log('i=',i)
B、let声明的变量只在块中有效(块级作用域"()")
var sum=0
for(let i=0;i<10;i++){ //用let来声明,i是一个局部变量
sum += i
}
console.log('sum=',sum)
console.log('i=',i)
可以看到‘i’出了块级作用域,被销毁:
C、const:声明的是常量,必须初始化并且不能重新赋值
(a)const声明的对象(常对象):可以改变对象属性的值,但不能改变对象本身.
①:改变属性值:张三改为了刘备
const obj = {
name:'张三',
age:28
}
console.log(obj)
obj.name='刘备'
console.log(obj)
②:const不能重新赋值,一旦重新赋值,会出现代码异常。
const obj = {
name:'张三',
age:28
}
console.log(obj)
obj.name='刘备'
console.log(obj)
obj = {
id:1001,
addr:'西安'
}
因为原来的对象已经赋值了,所以不能改变它的属性,重新改变属性,会出现异常,异常报错如下所示:
注: const定义变量必须赋初始值,let不需要赋初始值
☀️举例说明:
const num 错误写法
const num = 0 正确写法
let num / let num = 0 两种写法皆正确(b)冻结对象:用const声明对象,用Object.freeze(对象名)函数来冻结对象,这样就无法修改对象的属性值。
const obj = {
name:'张三',
age:28
}
console.log(obj)
Object.freeze(obj)//冻结obj对象
obj.name='刘备'
console.log(obj)//可以看到冻结对象后,对象的属性没有被改变过来,name属性依旧是张三
(c)如何冻结对象的内部对象:可以通过封装函数,在函数中采用循环方式,逐层对对象冻结
问题如下:对象的内部对象不能被冻结
const obj = {
name:'张三',
age:28,
family:{
father:{
name:'张安',
age:56
}
}
}
console.log(obj)
Object.freeze(obj)//冻结obj对象
obj.name='刘备'
obj.family.father.name = '张三丰'//冻结对象无法冻结嵌套的内部对象
console.log(obj)
解决办法:
//自定义冻结函数:逐层对对象进行冻结
//hasOwnProperty(key):作用是判断key是否有obj的属性
//typeof obj[key]:判断obj对象的key属性的类型
function deepFreeze(obj){
Object.freeze(obj)
for(let key in obj){
if(obj.hasOwnProperty(key)&& typeof obj[key]==='object'){
deepFreeze(obj[key])
}
}
}
console.log(obj)
// Object.freeze(obj)//无法冻结内部对象
deepFreeze(obj)
obj.family.father.name = '张三丰'
console.log(obj)
(2)临时死区
临时死区:JavaScript引擎在扫描代码时会在开辟两个区域一个是全局区域(存放var声明的变量),另一个是临时死区(存放let和const声明的变量)
(3)循环中let和const的使用
问题代码段如下:var提升作用域导致输出的i都是5.
let funArr = [] //数组:用来存放函数(数组的每一个单元都是一个函数)
for(var i=0;i<5;i++){
funArr.push(function(){//函数的功能是将当下的i打印出来
console.log(i)
})
}
funArr.forEach(function(item){
item()
});
a、在循环中创建函数
方法:用let来声明变量
let funArr = [] //数组:用来存放函数(数组的每一个单元都是一个函数)
for(let i=0;i<5;i++){
funArr.push(function(){//函数的功能是将当下的i打印出来
console.log(i)
})
}
funArr.forEach(function(item){
item()
});
b、for-in循环:用于遍历对象
// for -- in循环:遍历对象的属性
const obj ={
name:'张三',
age:25,
address:'西安',
sex:'男'
}
for(const key in obj){
console.log(key)
}
c、for-of循环:用于遍历数组
//for--of循环:用于遍历数组
const arr = ['AA','BB','CC','DD']
for(const item of arr){
console.log(item)
}
(4)解构赋值:rest操作符(…)
A、在调用函数时可以通过rest操作符传参
function fn(x,y,z){
console.log(x,y,z)
}
let arr = [11,22,33]
// fn(arr[0],arr[1],arr[2])//传统做法,传参
fn(...arr)//rest操作符,依次取出数组元素,将其赋给x,y,z参数
B、在遍历数组时使用rest操作符
let [a,b,c] =[11,22,33]
console.log(a,b,c)//输出11,22,33
let[t,...arr] = [10,20,30]//将10赋给t,将20,30赋给数组arr
console.log(t)
console.log(arr)
C、对象的解构:变量名必须和对象的属性名相同,和顺序没有关系
例1:可以看到,变量名和属性名相同,和顺序无关
let obj = {
uname:"张三",
age:25,
height:'178cm'
}
// let {n,a,h}=obj //变量名字必须与对象obj属性名字一致,负责赋不了值
let {age,height,uname}=obj //属性名字顺序无关,都可以打印出来
console.log(age,height,uname)
例2:变量名可以自定义,自定义方式如下所示:
let obj = {
uname:"张三",
age:25,
height:'178cm'
}
let {age:a,height:h,name:n}=obj //a,n,h是自定义变量名
console.log(a)
D、解构赋值中的默认值和参数
例1:
let obj = {
name:"张三",
age:25,
height:'178cm'
}
let {name,age,height='189cm'}=obj//height='189cm'就是默认值
//若obj对象不存在height属性,就使用这个默认值,若obj对象中存在height属性,则用obj里的height属性值
console.log('name:',name)
console.log('age:',age)
console.log('height:',height)
例2:
let obj = {
name:"张三",
age:25,
// height:'178cm'
}
function fn({name,age,height='189cm'}={}){
console.log(name,age,height)
}
fn(obj) //如果obj没有height属性,则打印出来的就是默认值
fn()//赋给fn一个空对象,打印出来就只有一个默认值
小练习
定义学生对象,包含name、computer(计算机课成绩)、english(英语成绩)定义数组有5个单元,每个单元中存放的是学生对象, 对数组中的所有学生按总成绩排序(降序)。
let arr =[]
for(let i=0;i<5;i++){
arr.push({
name:'A'+i, //拼接姓名
computer:Math.floor(Math.random()*60)+60,//计算机随机成绩60——120
english:Math.floor(Math.random()*90)+60//英语随机成绩60-150
})
}
console.log('排序前:')
arr.forEach(function(item){
console.log(item)
})
for(let i=0;i<arr.length;i++){
for(let j=i+1;j<arr.length;j++){
if(arr[i].computer+arr[i].english<(arr[j].computer+arr[j].english)){
let obj =arr[i]
arr[i]=arr[j]
arr[j]=obj
}
}
}
console.log('排序后:')
arr.forEach(function(item){
console.log(item)
})
4、模板字符串
(1)ES5中采用字符串拼接。例如:‘姓名:’+name+‘,性别’+sex
(2)ES6中采用反引号(``)实现,若需要用变量则采用${变量名}方式嵌入到反引号中。
☀️举个例子:
let arr =[
{
uname:'刘备',
age:35,
},
{
uname:'关羽',
age:28
},
{
uname:'张飞',
age:25
}
]
let str=''
for(let item of arr){
str +=`姓名:${item.uname},年龄:${item.age}\n`//注意反引号
}
console.log(str)
5、Symbol
(1)ES5的基本数据类型:number、boolean、undifined、null、string、object
(2)ES6新增的数据类型:Symbol,表示一个唯一的值。
A、使用方法:let 变量名 = Symbol 或 let 变量名 = Symbol(‘字符串’)
B、可以作为对象的属性名,也可以作为对象的属性值
const id1 =Symbol('111')
const id2 =Symbol('111')
let obj = {
id:id1,
name:'张三'
}
let obj2 ={
id:id2,
name:'李四'
}
console.log(obj)
console.log(obj2)
console.log(obj.id===obj2.id)