es6基礎(chǔ)
let和const命令
let和const用于聲明變量
let跟var的區(qū)別
1、let定義過(guò)的變量不能再定義,var定義過(guò)的變量可以重新定義
var name = 'tom';
var name = 'tony';
console.log(name); //輸出tony
let name = 'tom';
let name = 'tony';
console.log(name); //報(bào)錯(cuò) Identifier 'name' has already been declared name已經(jīng)被聲明
2、let定義的變量不會(huì)聲明提升,var聲明的變量會(huì)發(fā)生聲明提升
console.log(age); //輸出undefined var age會(huì)提升到console之前聲明 但不會(huì)賦值
var age = 18;
console.log(age); //報(bào)錯(cuò) age is not defined
let age = 18;
3、let定義的變量在let命令所在的代碼塊有效,var定義的變量在函數(shù)范圍內(nèi)有效
{
var age = 18;
let age1 = 19
}
console.log(age); //18
console.log(age1); //age1 is not defined
在{}里面 這是一個(gè)代碼塊 var的范圍是在函數(shù)里面
注:<script></script>里面的代碼會(huì)默認(rèn)在最外層加載一個(gè)function
let的范圍是在代碼塊
經(jīng)典案例
function box(){
var arr = [];
for(var i=0;i<5;i++){
arr[i] = function (){
return i
};
}
return arr;
}
console.log(box()[0]()) //輸出5
為什么會(huì)輸出5呢?
這是一個(gè)經(jīng)典的閉包,閉包是指有權(quán)訪問(wèn)另一個(gè)函數(shù)作用域中的變量的函數(shù)
在for循環(huán)里面的匿名函數(shù)執(zhí)行 return i 語(yǔ)句的時(shí)候,由于匿名函數(shù)里面沒(méi)有i這個(gè)變量,所以這個(gè)i他要從父級(jí)函數(shù)中尋找i,而父級(jí)函數(shù)中的i在for循環(huán)中,當(dāng)找到這個(gè)i的時(shí)候,是for循環(huán)完畢的i,也就是5,所以這個(gè)box得到的是一個(gè)數(shù)組[5,5,5,5,5]。
解決方法
自執(zhí)行函數(shù)
(function (){})()
通過(guò)給匿名函數(shù)傳參,而傳遞的這個(gè)參數(shù)i是每次執(zhí)行for循環(huán)里面的i,每次傳遞的參數(shù)i的值都不一樣,匿名函數(shù)里面的num接收傳遞的參數(shù)i,所以box()最終輸出結(jié)果為[0,1,2,3,4]
function box(){
var arr = [];
for(var i=0;i<5;i++){
arr[i] = (function (num){
return num
})(i);
}
return arr;
}
console.log(box()[0]) //輸出0
使用es6 let
使用es6 let的特性 let定義的變量在let命令所在的代碼塊有效
function box(){
var arr = [];
for(let i=0;i<5;i++){
arr[i] = function (){
return i
};
}
return arr;
}
console.log(box()0) //輸出0
const
一旦定義就不能修改
const a = 'aaa';
a = 'bbb'; //這時(shí)候會(huì)報(bào)錯(cuò) Assignment to constant variable
當(dāng) const聲明的變量為復(fù)雜數(shù)據(jù)類(lèi)型時(shí),可以改變里面的值
const obj = {
name:'張三',
age:18
}
obj.name = '李四';
console.log(obj) //這時(shí)候obj里面name的值變?yōu)槔钏牧?
是因?yàn)閺?fù)雜數(shù)據(jù)類(lèi)型是在堆內(nèi)存中存儲(chǔ)的,棧內(nèi)存中只存放地址。基礎(chǔ)數(shù)據(jù)類(lèi)型是在棧內(nèi)存中存儲(chǔ)的,所有聲明const a= 'aaa' 不能改變。而變量obj在棧內(nèi)存中存放的是一個(gè)地址,堆內(nèi)存中對(duì)象的值變了,并不影響棧內(nèi)存的地址。所以obj的值變了,且不報(bào)錯(cuò)
數(shù)組結(jié)構(gòu)解析
作用:從對(duì)象或者數(shù)組中取值,然后對(duì)變量進(jìn)行賦值
數(shù)組的結(jié)構(gòu)解析:按照對(duì)應(yīng)的位置,把等號(hào)右邊的數(shù)組中的值給等號(hào)左邊的變量。數(shù)組可以嵌套
注意點(diǎn):1、如果解析不成功,變量的值為undefined。2、等號(hào)右邊不是數(shù)組會(huì)報(bào)錯(cuò)
let [a,b,c] = [1,2,3];
console.log(a,b,c); // 輸出1,2,3
let [a,b,c] = [1,2];
console.log(a,b,c); //輸出 1,2,undefined
let [a,b,c = 4] = [1,2];
console.log(a,b,c); //輸出 1,2,4
let [a,b,c = 4] = [1,2,5];
console.log(a,b,c); //輸出 1,2,5
let [a,b,c] =11;
console.log(a,b,c); //報(bào)錯(cuò)
對(duì)象的結(jié)構(gòu)解析
let {name:name,age:age} = {name:'張三',age:18};
console.log(name,age); //輸出張三 18
//可簡(jiǎn)寫(xiě)為
let {name,age} = {name:'張三',age:18};
console.log(name,age); //輸出張三 18
模板字符串
`字符串${js表達(dá)式}`
擴(kuò)展運(yùn)算符
擴(kuò)展運(yùn)算符 ...
數(shù)組的擴(kuò)展運(yùn)算
數(shù)組的擴(kuò)展運(yùn)算就是將一個(gè)數(shù)組轉(zhuǎn)換為用逗號(hào)分割的參數(shù)列表
用于數(shù)組的解析
let arr = [11,22,33,44];
console.log(...arr); // 解析為11,22,33,44
用于方法的參數(shù)
情景一
function show (n1,n2,n3){
console.log(n1,n2,n3)
}
let arr = [11,22,33]
show(...arr)
情景二
function sum (...arr){ //也可以用arguments
let result = 0;
for(let i = 0;i<arr.length;i++){
result +=arr[i];
}
}
sun(...[11,22,33,44])
擴(kuò)展運(yùn)算符拷貝的數(shù)組屬于深copy
同樣屬于深copy的還有array.concat(); array.slice()
數(shù)組的擴(kuò)展運(yùn)算
let obj1 = {name:'tom',age:'18',friend:{name:'張三',age:18}}
let obj2 = {...obj1}
obj2.name='王麻子'
console.log(obj1,obj2); //{name: "tom", age: "18", friend: {name:'張三',age:18}} {name: "王麻子", age: "18", friend: {name:'張三',age:18}}
你會(huì)發(fā)現(xiàn)obj2的name值變了 obj1的沒(méi)變。
let obj1 = {name:'tom',age:'18',friend:{name:'張三',age:18}}
let obj2 = {...obj1}
obj2.name='王麻子'
obj2.friend.name='張麻子'
console.log(obj1,obj2); //{name: "tom", age: "18", friend: {name:'張麻子',age:18}} {name: "王麻子", age: "18", friend: {name:'張麻子',age:18}}
你會(huì)發(fā)現(xiàn)obj1.friend,obj2.friend的name值都變了 所以數(shù)組的擴(kuò)展運(yùn)算拷貝對(duì)象不是深拷貝