1、var聲明的變量是函數(shù)作用域的,存在變量的提升。(變量的聲明會(huì)被提前到當(dāng)前作用域的最前面)
1 //變量提升 2 function f(condition){ 3 if(condition){ 4 var value="blue"; 5 return value; 6 } 7 else{ 8 console.log(value); //undefined 9 }10 console.log(value); //undefined11 }12 f(false);
由于var聲明的變量存在變量提升,所以當(dāng)condition為false時(shí),輸出變量不會(huì)提示value變量未定義的錯(cuò)誤,上面的代碼類似于
1 //變量提升 2 function f(condition){ 3 var value; 4 if(condition){ 5 value="blue"; 6 return value; 7 } 8 else{ 9 console.log(value); //undefined10 }11 console.log(value); //undefined12 }13 f(false);
1 var value=10;2 var value="100";3 console.log(value)//100
使用var聲明的全局變量會(huì)自動(dòng)綁定為全局對(duì)象的屬性。從而又可能覆蓋已經(jīng)存在的全局屬性。
1 console.log(global.RegExp);//[Function: RegExp]2 var RegExp="aaa";3 console.log(global.RegExp);//"aaa"
代碼不要寫(xiě)在js文件中使用node 文件名去測(cè)試,因?yàn)閚ode會(huì)把一個(gè)文件作為一個(gè)模塊,聲明的變量不是全局對(duì)象的屬性。
可以node的repl中測(cè)試或者瀏覽器環(huán)境中。
使用let和const聲明的變量不會(huì)覆蓋全局對(duì)象的屬性,而是遮蓋他
1 let RegExp="aaa";2 console.log(global.RegExp===RegExp);//false
通過(guò)let和const聲明的變量是塊級(jí)作用域,只在{}生效;類C語(yǔ)言多采用塊級(jí)作用域,這樣做更符合我們的習(xí)慣。
a、let聲明的變量是塊級(jí)作用域,且不存在變量提升機(jī)制,所以使用let聲明的 變量只有放到當(dāng)前作用域的最前面,才能在整個(gè)作用域中使用。
1 function f(condition){ 2 if(condition){ 3 let value="blue"; 4 return value; 5 } 6 else{ 7 //console.log(value); //ReferenceError: value is not defined 8 } 9 console.log(value); //ReferenceError: value is not defined10 }11 f(true);
變量離開(kāi)if塊就會(huì)被銷毀,其他的塊作用由于沒(méi)有什么變量vaue,所以直接使用會(huì)拋出異常。
b、let聲明的變量在同一作用域中禁止重復(fù)聲明
1 //var value=10;2 let value=10;3 let value="100";//SyntaxError: Identifier 'value' has already been declared4 console.log(value)//100
當(dāng)在不同的作用域聲明變量的時(shí)候,不會(huì)報(bào)錯(cuò)。
1 //var value=10;2 let value=10;3 function f(){4 let value="1dad";5 console.log(value)//'1dad'6 }7 console.log(value)//108 f()
const聲明
a.const關(guān)鍵字用來(lái)聲明一個(gè)常量,聲明后變量的值不可以更改。const聲明變量必須初始化。
1 const a='dada'2 const b;//SyntaxError: Missing initializer in const declaration
b、const聲明已存在的變量會(huì)報(bào)錯(cuò),(無(wú)論是let和const)
var a=10;//let a=10const a='dada'//Identifier 'a' has already been declared
c、用const聲明對(duì)象
const聲明的變量不允許修改變量的值。由于變量存在的是對(duì)象的值得引用,所以const聲明的對(duì)象可以修改對(duì)象的屬性,但是不能把修改對(duì)象的引用。
const a={name:'yiluhuakai'};a.name="aaa";console.log(a.name)//'aaa'a={};//TypeError: Assignment to constant variable.
使用let和const聲明的變量不會(huì)進(jìn)行變量提升,變量的作用域的開(kāi)始到變量聲明之前的位置成為臨時(shí)死區(qū),當(dāng)在該區(qū)域使用變量時(shí)回拋出異常,即使是使用相對(duì)安全的typeof操作符?! ?/p>
typeof a;//作用域外不會(huì)拋出異常function f(){ // typeof a;//ReferenceError: a is not defined if(true) { ; } let a=10;}f();
在循環(huán)中定義一個(gè)函數(shù),打印當(dāng)前的循環(huán)的變量i;
1 var arr=[]; 2 for(var i=0;i<10;i++){ 3 arr.push(function(){ 4 console.log(i); 5 }) 6 } 7 //打印 8 arr.forEach(function(item){ 9 item();//輸出10次1010 })
為什么輸出結(jié)果是10次10呢,因?yàn)樯厦鎣ar聲明的便利會(huì)提升到循環(huán)外面,循環(huán)中函數(shù)共享(閉包)同一個(gè)i。
立即調(diào)用調(diào)用函數(shù)可以解決這個(gè)問(wèn)題?! ?/p>
1 var arr = []; 2 for (var i = 0; i < 10; i++) { 3 arr.push((function (value) { 4 return function () { 5 console.log(value) 6 } 7 })(i)) 8 } 9 //打印10 arr.forEach(function (item) {11 item();//0 1 2 ... 8 912 })
將i作為行參傳給函數(shù),value會(huì)復(fù)制i的值,這個(gè)之就是內(nèi)部函數(shù)打印的值。
更簡(jiǎn)單的解決辦法:使用let使命變量
1 var arr=[]; 2 for(let i=0;i<10;i++){ 3 arr.push(function(){ 4 console.log(i); 5 }) 6 } 7 //打印 8 arr.forEach(function(item){ 9 item();//輸出0 1 ... 8 910 })
使用let聲明的變量每次循環(huán)都會(huì)聲明一個(gè)新的變量,所以之前迭代的同名變量初始化j將其初始化,所以每次輸出的值都不一樣。
for-in和for-of也是一樣。
1 var arr=[]; 2 var object={ 3 a:true, 4 b:1, 5 c:2 6 } 7 for(let key in object){ 8 arr.push(function(){ 9 console.log(key)10 })11 }12 arr.forEach(function(item){13 item() //a b c14 })
使用let會(huì)每次聲明一個(gè)新的變量保存key,所以會(huì)每次輸出不同的值。使用var使用的是同一個(gè)變量,最終輸出都是c.
const用在循環(huán)中
1 var arr=[]; 2 for(const i=0;i<10;i++){ 3 arr.push(function(){ 4 console.log(i); 5 }) 6 } 7 //打印 8 arr.forEach(function(item){ 9 item();//TypeError: Assignment to constant variable.10 })
在普通的for循環(huán)中使用const聲明變量時(shí),第一次循環(huán)const i=0不會(huì)報(bào)錯(cuò),但是當(dāng)?shù)诙窝h(huán)中初始化i后,對(duì)i執(zhí)行i++操作時(shí)會(huì)報(bào)錯(cuò)。所以不能在普通的循環(huán)中使用const聲明循環(huán)變量。
但是在for-of和for-in循環(huán)中使用const不會(huì)出現(xiàn)問(wèn)題,因?yàn)橹粫?huì)對(duì)新創(chuàng)建的變量初始化,不會(huì)去改變變量的值。
聯(lián)系客服