1. let關(guān)鍵字
let的用途:
在之前寫js時候羡藐,用var來聲明一個變量贩毕,es6里面除了var還有其他的聲明變量的關(guān)鍵字,let就是其中之一仆嗦,那么let的用途就是用來聲明變量的辉阶。
let與var
既然都是聲明變量的關(guān)鍵字,那肯定就有區(qū)別瘩扼,要不就不會有第二個了谆甜,看看有什么區(qū)別。
使用 var 的不足之處:
1.var聲明的變量作用于函數(shù)內(nèi)集绰,let聲明的變量作用與塊級作用域规辱。
任何一對“大括號{ }”中的語句都屬于一個塊,在大括號里面用let定義的所有變量在大括號外是不可見的栽燕,我們稱之為塊級作用域罕袋。
2.用var聲明變量的時候會導(dǎo)致“變量提升”。
JavaScript的函數(shù)定義有個特點碍岔,它會先掃描整個函數(shù)體的語句浴讯,把所有申明的變量“提升”到函數(shù)頂部:
'use strict';
function foo() {
var x = 'Hello, ' + y;
alert(x);
var y = 'Bob';
}
foo();
雖然是strict模式,但語句var x = 'Hello, ' + y;
并不報錯蔼啦,原因是變量y
在稍后申明了榆纽。但是alert
顯示Hello, undefined
,說明變量y
的值為undefined
询吴。這正是因為JavaScript引擎自動提升了變量y
的聲明掠河,但不會提升變量y
的賦值亮元。
對于上述foo()
函數(shù)猛计,JavaScript引擎看到的代碼相當于:
function foo() {
var y; // 提升變量y的申明
var x = 'Hello, ' + y;
alert(x);
y = 'Bob';
}
如果用let重寫foo()
:
'use strict';
function foo() {
var x = 'Hello, ' + y;
alert(x);
let y = 'Bob';
}
foo(); //結(jié)果:報錯 y is not defined
用let關(guān)鍵字來定義y
;這樣y
在代碼塊內(nèi)就不會提升了爆捞。報錯是因為用let聲明的變量要先聲明再使用奉瘤,上面代碼里未聲明定義就使用,就只有報錯了煮甥。
使用let的注意點:
注意1:同一個塊級作用域內(nèi)盗温,不允許重復(fù)聲明同一個變量。
// 錯誤示范一:
{
var a =1;
let a =2; //報錯成肘,因為a已經(jīng)用var聲明過
}
// 錯誤示范二:
{
let a =1;
let a= 2; //還是報錯卖局,a已經(jīng)用let聲明過。
}
注意2:函數(shù)內(nèi)不能用let重新聲明函數(shù)的參數(shù)
// 錯誤示范:
function say(word){
let word = 'hello Jack'; //報錯:用let重新聲明word參數(shù)
alert(word)
}
say('hello Lili');
// 函數(shù)內(nèi)用let重新聲明word這個參數(shù)双霍,會報錯的砚偶,千萬別這么干批销。
2. const關(guān)鍵字
const 的作用
const是constant(常量)的縮寫,const和let一樣染坯,也是用來聲明變量的均芽,但是const是專門用于聲明一個常量的,顧名思義单鹿,常量的值是不可改變的掀宋。
常量的特點:
1、不可修改
const Name = '張三';
Name = '李四'; // 錯誤仲锄,企圖修改常量Name
2劲妙、只在塊級作用域起作用,這點與let關(guān)鍵字一樣儒喊。
if(1){
const Name = '張三';
}
alert(Name); //錯誤是趴,在代碼塊{ }外,Name失效
3澄惊、不存在變量提升唆途,必須先聲明后使用,這點也跟let關(guān)鍵字一樣掸驱。
if(1){
alert(Name);//錯誤肛搬,使用前未聲明
const Name = '張三';
}
4、不可重復(fù)聲明同一個變量毕贼,這點跟let也一樣温赔。
var Name = '張三';
const Name = '李四';//錯誤,聲明一個已經(jīng)存在的變量Name
5鬼癣、聲明后必須要賦值
const NAME; //錯誤陶贼,只聲明不賦值
使用const的注意點:
const Person = {"name":"張三"};
Person.name = "李四";
Person.age = 20;
console.log(Person);
//結(jié)果:正常輸出{name: "李四", age: 20}
如上常量是一個對象,常量是可以修改的待秃,為什么呢拜秧?
這里用到了傳址賦值,什么叫傳址賦值章郁?
傳址:在賦值過程中枉氮,變量實際上存儲的是數(shù)據(jù)的地址(對數(shù)據(jù)的引用),而不是原始數(shù)據(jù)或者數(shù)據(jù)的拷貝暖庄。
用const來聲明一個對象類型的常量聊替,就是傳址賦值。而不可修改的是對象在內(nèi)存中的地址培廓,而不是對象本身惹悄。
所以,這就很好的解釋剛剛的這段代碼為什么不會報錯肩钠,而是正常輸出了泣港。
上面代碼中修改的只是Person本身象缀,修改的是name屬性和增加一個屬性age,而地址沒變爷速,也不可變央星,所以并沒有違背常量不可修改的約定。
但是惫东,如果這樣寫呢莉给,就會報錯:
const Person = {"name":"張三"};
Person.age = 20;
Person = {};
//錯誤,企圖給常量Person賦新值(新地址)
3. 解構(gòu)賦值
官方的解釋:
ES6允許按照一定模式廉沮,從數(shù)組和對象中提取值颓遏,對變量進行賦值,這被稱為解構(gòu)(Destructuring)滞时。
上一段代碼進一步解釋一下什么叫解構(gòu)賦值:
var arr = [1,2,3]; // 把數(shù)組的值分別賦給下面的變量叁幢;
var a = arr[0];
var b = arr[1];
var c = arr[2];
console.log(a); // a的值為1
console.log(b); // b的值為2
console.log(c); // c的值為3
以上是傳統(tǒng)的變量賦值,將數(shù)組的元素值1坪稽,2曼玩,3分別賦值給變量a,b窒百,c黍判,結(jié)果也是如我們所愿,賦值成功篙梢。
var [a,b,c] = [1,2,3]; //把數(shù)組的值分別賦給下面的變量顷帖;
console.log(a); // a的值為1
console.log(b); // b的值為2
console.log(c); // c的值為3
以上是變量的解構(gòu)賦值,賦值的代碼減少了渤滞,只需要將變量a贬墩,b,c作為一個數(shù)組的元素妄呕,然后將數(shù)組[1,2,3]賦值給數(shù)組[a,b,c]即可陶舞,變量a,b趴腋,c即可分別得到對應(yīng)的值燎竖,這種叫做數(shù)組的解構(gòu)賦值巷怜。
數(shù)組的解構(gòu)賦值注意點:
1、結(jié)構(gòu)賦值可以嵌套的
var [ a,b,[ c1,c2 ] ] = [ 1,2,[ 3.1,3.2 ] ];
console.log(c1); // 結(jié)果:c1的值為3.1
console.log(c2); // 結(jié)果:c2的值為3.2
2境蔼、不完全解構(gòu)
var [a,b,c] = [1,2];
console.log(a); // 結(jié)果:a的值為1
console.log(b); // 結(jié)果:b的值為2
- 賦值不成功厅贪,變量的值為undefined
var [a,b,c] = [1,2];
console.log(a); // 結(jié)果:a的值為1
console.log(b); // 結(jié)果:b的值為2
console.log(c); // 結(jié)果:c的值為undefined
- 允許設(shè)定默認值
var [a,b,c=3] = [1,2];
console.log(a); // 結(jié)果:a的值為1
console.log(b); // 結(jié)果:b的值為2
console.log(c); // 結(jié)果:c的值為3
- 重新賦值會覆蓋默認值
var [a,b,c=3] =[1,2,4];
console.log(a); // 結(jié)果:a的值為1
console.log(b); // 結(jié)果:b的值為2
console.log(c); // 結(jié)果:c的值為4
?? 注意:當新的值為undefined的時候蠢护,是不會覆蓋默認值的。
對象的解構(gòu)賦值
對象的解構(gòu)賦值跟數(shù)組的解構(gòu)賦值很類似养涮,上代碼:
var {a, b, c} = {a: 1, b: 2, c: 3};
console.log(a); // 結(jié)果:a的值為1
console.log(b); // 結(jié)果:b的值為2
console.log(c); // 結(jié)果:c的值為3
對象的解構(gòu)賦值不會受到屬性的排列次序影響(數(shù)組則會受影響)葵硕,它是跟屬性名關(guān)聯(lián)起來的眉抬,變量名要和屬性名一致,才會成功賦值懈凹。
var { a, b, c } = {a: 1, c: 3, b: 2};
console.log(a); // 結(jié)果:a的值為1
console.log(b); // 結(jié)果:b的值為2
console.log(c); // 結(jié)果:c的值為3
如果變量找不到與其名字相同的屬性蜀变,就會賦值不成功:
var { a } = {"b":2};
console.log(a); // 結(jié)果:a的值為undefined
?? 變量名與屬性名不一樣的變量解構(gòu)賦值:
var { b: a} = {b: 2};
console.log(a); // 結(jié)果:a的值為2
對象的結(jié)構(gòu)賦值注意點:
1、對象解構(gòu)賦值可以嵌套
var {a: 介评} = {a: {b: 1}};
console.log(b); // 結(jié)果:b的值為1
2库北、可以指定默認值
var {a, b=2} = {a: 1};
console.log(b); // 結(jié)果:b的值為默認值2
字符串的解構(gòu)賦值
除了對象和數(shù)組可以解構(gòu)賦值外,字符串也可以結(jié)構(gòu)賦值们陆,上代碼:
var [a, b, c, d, e, f] = "熱忱一直在寒瓦!";
console.log(a); // 熱
console.log(b); // 忱
console.log(c); // 一
console.log(d); // 直
console.log(e); // 在
console.log(f); // !
解構(gòu)賦值的用途
一坪仇、交換變量的值
var x = 1;
var y = 2;
[x, y] = [y, x];
簡單的一行代碼即可成功交換x杂腰,y的值。
二椅文、提取函數(shù)返回的多個值
函數(shù)只能返回一個值喂很,我們可以將多個值裝在一個數(shù)組或者對象中,再用解構(gòu)賦值獲取其中的值皆刺。
function foo(){
return {name: "neo", age: 31}
}
var {name, age} = foo();
console.log(name); // 結(jié)果:neo
console.log(age); // 結(jié)果:31
將foo()的返回值直接通過結(jié)構(gòu)賦值賦給變量name和age恤筛,實現(xiàn)快速的提取對應(yīng)的值。
三芹橡、定義函數(shù)參數(shù)
function foo({name, age}){
console.log(`姓名:${name}`);
console.log(`年齡:${age}`);
}
foo({name: "neo", age: "31", sex: "male"});
通過這種寫法毒坛, 很方便就能獲取JSON對象中想要的參數(shù),例如案例中林说,只需要獲取實參中的:name煎殷,age而不需要管其他的參數(shù)。