目录
ES6
一、let&const特性
- 不属于顶层对象window
- 不允许重复声明
- 不允许变量提升
- 暂时性死区(在变量未声明之前不能赋值)
- 块级作用域
1 let&var比较
if(false){
//var a=5
}
console.log(a);//Uncaught ReferenceError: a is not defined at
var变量提升
//var变量提升
if(false){
var a=5
}
console.log(a);//undefined
//上面的代码等价于下面的代码
var a
if(false){
a=5
}
console.log(a);//undefined
//可以发现,a变量提升,条件为false,a没有被赋值,在全局作用域下声明,作为window的属性
es5只有函数作用域和全局作用域,在if代码中用var声明的变量属于顶层对象window
if(true){
var a=5
}
console.log(a);//5
console.log("window.a :",window.a);//window.a :5
console.log(a===window.a);true
let块级作用域,块级作用域外访问不到变量
//let块级作用域
if(true){
let a=5
}
console.log(a);Uncaught ReferenceError
经典面试题
for(var i=0;i<3;i++){
setTimeout(function(){
console.log(i)
},0)
}
输出 3 3 3
原因:
与浏览器event loop相关
- setTimeout是异步任务,for循环同步任务
- 浏览器会先执行所有的同步任务,在执行异步任务
- 执行三次for循环后,此时i=3
- 再执行setTimeout中的回调函数是i已经是3,所有输出三次3
解决方案
- 闭包
for(var i=0;i<3;i++){
(function(i){
setTimeout(function(){
console.log(i)
},0)})(i)
}
输出:
0
1
2
- let
for(let i=0;i<3;i++){
setTimeout(function(){
console.log(i)
},0)
}
输出:
0
1
2
解决方案let代码使用babel进行es6转换es5结果,发现其与闭包一致
2 const
1.2.1 es5定义常量
Object.defineProperty(window,'a',{
value:"hello",
writable:false
})
console.log(a);
1.2.2 const定义常量
当const定义的变量赋值为基本数据类型值,如number,string,变量不可重新赋值
const a = 5
console.log(a);
a=6// Uncaught TypeError: Assignment to constant variable.不能给常量重新赋值
当const定义的变量赋值为基本对象时,可修改对象的属性值和添加属性值
const obj = {
name:'jae',
age:18
}
console.log(obj);
obj.height = 188
console.log(obj);
但是不能给const变量重新赋值对象
原因:
对象在栈内存中存储的是指针,修改对象的属性值并不会修改栈内存存储的地址,此时修改的是指针指向的堆中值;但如果重新给变量赋值对象,相当于修改栈内存存在的地址
obj = {
name:'brian',
age:19
}
可使用Object.freeze让对象的属性值不被修改
Object.freeze(obj)
obj.name="brian"
console.log(obj);
但freeze只能冻住浅层的属性,若浅层还有对象,仍可以修改对象中的属性值
const obj = {
name:'jae',
age:18,
grade:{
math:80,
english:70
}
}
Object.freeze(obj)
obj.grade.math=88
console.log(obj);
二、解构赋值
2.1 数组解构
=左边和右边变量一一对应,超出的为undifined
let [a,b,[c,d],e]=[1,2,[3,4]]
console.log(a,b,c,d,e)// 1 2 3 4 undifined
let [a,b,c]=[1,2,[3,4]]
console.log(a,b)//1 2
console.log(c)//[3,4]
有默认值时,若未赋值,输出默认值
//e有默认值,且右边没有赋值,则为默认值
let [a,b,[c,d],e=5]=[1,2,[3,4]]
console.log(a,b,c,d,e) //1 2 3 4 5
2.2 惰性赋值
function foo(){
console.log('abc')
}
//右边赋值,左边函数不会执行
let [x=foo()] = [7]
console.log('x--',x)//7
//右边未赋值,左边函数执行,没有返回值,y为undefined
let [y=foo()] = []
console.log('y--'y)
2.3 对象解构
let person = {
name:'jae',
age:28
}
let {name, age} = person
console.log(name,age);//jae 28
更换key位置,赋值仍正确
let person = {
name:'jae',
age:28
}
let {age, name} = person
console.log(name,age);//jae 28
2.3.1 对象起别名
let person = {
name:'jae',
age:28
}
let {name:uname, age:uage} = person
//console.log(name,age);//报错,key已更换
console.log(uname,uage);
2.4 字符串解构
let [a,b,c,d] = 'yarn'
console.log(a,b,c,d)//y a r n
2.5 应用
2.5.1 提取json数据
let json = '{"a":"hello","b":"world"}'
let {a,b} = JSON.parse(json)
console.log(a,b);