菜鳥學(xué)前端
本文:https://blog.csdn.net/CrazyApes/article/details/128957891
@[toc]
說實話召烂,在看到這個之前奏夫,我只知道 var
,以前也只用過這玩意廊谓。
后面那倆都不知道是干啥用的麻削。
感謝同桌的提示。
記叠荠!
var
var
是 ES5
提出的扫责。用于聲明變量。
什么是
ES5
者娱?
ES5
全稱ECMAScript5
黄鳍,即 ES5平匈,是ECMAScripts的第五次修訂(第四版因為過于復(fù)雜廢棄了)藏古,又稱ECMAScript2009校翔,于 2009 年完成標(biāo)準(zhǔn)化灾前。
var num = 1;
var str = 'a';
var fun = function(){};
var obj = {};
var bean = new ABC(); /* 需要提前聲明過ACB這個類型 */
var
就是一切哎甲,想是啥就可以是啥,而且是 弱類型貌虾。就算是賦值完了還可以賦值為其它類型的值。
當(dāng)然因為是重復(fù)賦值衔憨,肯定只有最后一次有效袄膏。
var any = 1;
any = 'a';
any = function(){};
any = {};
any = new ABC(); /* 需要提前聲明過ACB這個類型 */
any = false;
console.log(any);
// print
false
var
還可以重復(fù)聲明沉馆,就是說即使你聲明過變量any
,還可以再次聲明 any
揖盘。
同樣的锌奴,因為是同一個變量名,后者肯定會覆蓋前者椭符。
上面那段代碼還可以這么寫耻姥。
var any = 1;
var any = 'a';
var any = function(){};
var any = {};
var any = new ABC(); /* 需要提前聲明過ACB這個類型 */
var any = false;
console.log(any);
// print
false
var
還可以 變量提升 !U艚 !啥是變量提升似忧? 額盯捌,大概是把自己變牛逼了。
你看箫攀,它可先使用幼衰,后聲明。
console.log(any);
var any = false;
// print
undefined
后來才了解到有個什么預(yù)解析過程梢睛,會提前加載這個變量识椰。
類似于如下:
var any;
console.log(any);
any = false;
// print
undefined
這樣一來,結(jié)合以上特征挤牛,代碼開始漸漸奇怪起來种蘸。
for(var index = 0;index < 10; index++ ){
/* do something */
}
...
/* n 多代碼之后 */
...
/* 腦抽了航瞭,突然想聲明個index用來做某個標(biāo)記位 */
var index;
if (index) {
console.log('already init !!!');
console.log('index value:' + index);
} else {
/* init something */
console.log('init index');
index = 1;
}
// print
already init !!!
index value: 10
唉,啥情況章办,哪來的10滨彻??休偶?
大家可能說辜羊,上面那個for
循環(huán)的鍋词顾。
但是在多人協(xié)作的情況下肉盹,代碼沒報錯疹尾,執(zhí)行結(jié)果卻不是你想要的。
而且這種情況下睡雇,排查是個非常困難的事,因為真不知道誰在哪個地方突然聲明了一個一樣的變量秕豫。
而且再極端一些,那個for
循環(huán)假設(shè)只在某些條件下才執(zhí)行祠墅。
那么剛才那個代碼就成了歌径,你這個bug偶爾出現(xiàn),偶爾消失狗准。
let和const
let
和 const
都是 ES6 提出的腔长。一個用于聲明變量验残,一個用于聲明常量。
什么是
ES6
鸟召?
ES6氨鹏, 全稱ECMAScript 6.0
,即 ES6槽片,是ECMAScripts的第六次修訂,又稱 ES2015还栓,于2015年06 月發(fā)版,是 JavaScript 的下一個版本標(biāo)準(zhǔn)谷婆。
ES6
中有了塊級作用域的概念辽聊,let
和 const
都是塊級作用域。以 {}
代碼塊作為作用域范圍异袄,只能在代碼塊里面使用玛臂,不存在變量提升,只能先聲明再使用讽营,否則會報錯橱鹏。
if (true) {
let a = 'let';
var b = 'var';
}
console.log(b); // var
console.log(a); // Uncaught ReferenceError: a is not defined
console.log(c); // Uncaught ReferenceError: c is not defined
let c = 'c'
在代碼塊內(nèi)堪藐,在聲明變量之前,該變量都是不可用的贮勃。
這在語法上苏章,稱為“暫時性死區(qū)”(temporal dead zone,簡稱 TDZ)泉孩,在同一個代碼塊內(nèi)并淋,不允許重復(fù)聲明。只要塊級作用域內(nèi)存在let命令句喷,它所聲明的變量就“綁定”(binding)這個區(qū)域,不再受外部的影響唾琼。不同代碼塊是可以重復(fù)聲明的。
let a = 'let a'
if (true) {
let a = 'let if a';
console.log(a); // print 'let if a'
let a = 'next same let'
console.log(a); // Uncaught SyntaxError: Identifier 'a' has already been declared
}
console.log(a); // print 'let a'
const 聲明的是一個只讀常量赶舆,在聲明時就需要賦值芜茵。(如果 const 的是一個對象倡蝙,
對象所包含的值是可以被修改的。抽象一點兒說蒸辆,就是對象所指向的地址不能改變析既,而變量成員是可以修改的眼坏。)
const any = 'abc';
const obj = {};
除了不可重復(fù)賦值的問題酸些,其它和 let
作用域類似,功能類似沿侈。
寫不動了
寫不動了市栗。。蛛淋。后面有想法了再慢慢了解和補充篡腌。。