- var有預(yù)解析,alert(a);var a=5;先使用,后定義也仍然不會報錯,只是獲取不到后面賦的值。因為變量提升(只要在同個作用域有定義就能預(yù)解析)。相當于 var a;alert(a); a=5;//undefined;因此如果先使用,后面賦值與否沒有意義。
var a=12;
function fn() {
alert(a);
var a=5;
}
fn();//undefined,即a有定義了但后面才賦值
等同于
function fn() {
var a;
alert(a);
a=5;
}
let沒有預(yù)解析,alert(b);let b;//b is not defined 先使用后定義會報錯。另外在函數(shù)作用域外定義過同樣的變量,在內(nèi)部執(zhí)行如上代碼仍然無法獲取值。var同樣。
var b=12;
function fn() {
alert(b);//TDZ 暫時性死區(qū)
let b;
}
fn();////b is not defined,沒有變量提升,因此報錯提示b沒有定義
在同個作用域,var 重復(fù)定義下一個的值會覆蓋上一個,let會報錯,提示已經(jīng)定義過。
- var 定義的變量只有在全局和函數(shù)內(nèi)有作用域,在塊級作用域內(nèi)定義仍然是全局變量。
for(var i=0;i<10;i++){
}
console.log(i);//10
一般{}即是快級作用域,如if(){}; for(){} ;while(){};
for(let i=0;i<10;i++){
let i=abc;
console.log(i);//abc abc 10個
}
console.log(i);//is not defined報錯
for循環(huán)相當于父級作用域,里面的{}是子作用域,作用域可以無限嵌套,所以{}里的i不算重復(fù)定義。和函數(shù)一樣若使用變量會向上尋找定義的地方,子作用域找不到定義會一層層去找父級作用域。若當前作用域定義了但未賦值,則提示undefined,而不會再去找父級作用域。若在當前作用域使用之后定義了,則會報is not defined的錯,也不會再去父級找。
let j="888";
for(let i=0;i<10;i++){
//let j;//定義在此輸出undefined 10次
console.log(j);//
let j;//定義在此報is not defined,無法繼續(xù)
}
- let相較于var的優(yōu)勢體現(xiàn),類似選項卡功能,應(yīng)用數(shù)個按鈕切換。for循環(huán)若換成var則因為i是全局變量循環(huán)結(jié)果為按鈕的數(shù)量而無法實現(xiàn)。
window.onload=function(){
var myBtn=document.querySelectorAll("input");
for(let i=0;i<myBtn.length;i++){
myBtn[i].onclick=function () {
console.log(i);//點擊輸出按鈕的index,如0,1,2
}
}
}
- const特性和let一樣,定義的是常量,不能修改。定義的時候必須賦值。即不能光定義不賦值,也不能先定義后賦值。并不是變量的值不能修改,而是指向的那個內(nèi)存地址不得改動。對于簡單類型的數(shù)據(jù)(數(shù)值、字符串、布爾值),值就保存在變量指向的那個內(nèi)存地址,因此等同于常量。
但對于復(fù)合類型的數(shù)據(jù)(主要是對象和數(shù)組),變量指向的內(nèi)存地址,保存的只是一個指針,const只能保證這個指針是固定的,不管它指向的數(shù)據(jù)結(jié)構(gòu)是否可變。因此,將一個對象聲明為常量必須非常小心。
const d;
d=12;
console.log(d);//Missing initializer in const declaration 報錯
const dblink = 5;
dblink=12;//Assignment to constant variable.報錯
const arrB=['apple','banana'];
//arrB=[];//會報錯
arrB.push('orange');//可以添加,因為是對arrB對象的引用,不是修改對象的本身
arrB[0]='strawberry';//可以修改
//配置文件演示
const config={
host:'',
username:'',
password:'',
version:''
}
config.username="vivi";//可以
config=false;//報錯
//徹底無法修改的方法
const arrC=Object.freeze(['apple','banana']);
arrC.push('orange');
console.log(arrC);//Cannot add property 2, object is not extensible凍結(jié)引用后也無法修改
- 立即執(zhí)行匿名函數(shù)。自執(zhí)行函數(shù)
(function(){
//TODO
})()
//等同于
{
//TODO
}