這幾天修改別人的js,發現聲明變量有的用var,有的用let,那它們有什麼區別呢?javascript
javascript中聲明變量的方式有:var
、let
、const
java
1.var面試
(1)做用域:數組
整個函數範圍內,或者是全局的 異步
function func() { if (true) { var str = 'hello world'; } console.log(str); }
輸出:函數
hello world
(2)容許在相同做用域內重複聲明同一個變量spa
var var1 = 'var1 first.'; var var1 = 'var1 second.'; console.log(var1);
輸出:線程
var1 second.code
(3)var能夠先使用,後聲明blog
var1 = 'var1 first.'; var var1; console.log(var1);
輸出:
var1 first.
(4)聲明後未賦值
var var1; console.log(var1);
輸出:
undefined
2.let
(1)做用域:
只在let命令所在的代碼塊內({})有效
function func() { if (true) { let str = 'hello world'; } console.log(str); }
報錯:
Uncaught ReferenceError: str is not defined
(2)不容許在相同做用域內重複聲明同一個變量
let var1 = 'var1 first.'; let var1 = 'var1 second.'; console.log(var1);
報錯:
Uncaught SyntaxError: Identifier 'var1' has already been declared
(3)let必須先聲明後使用
var1 = 'var1 first.';
let var1;
console.log(var1);
報錯:
Uncaught ReferenceError: var1 is not defined
(4)聲明後未賦值
let var1;
console.log(var1);
輸出
undefined
3.const
const聲明一個只讀的常量
(1)做用域:
只在聲明所在的塊級做用域內有效
{ const PI = 3.1415; } console.log(PI);
報錯:
Uncaught ReferenceError: PI is not defined
正確的使用位置
{ const PI = 3.1415; console.log(PI); }
輸出:
3.1415
(2)聲明以後值就不能改變
const PI = 3.1415;
PI=3;
報錯:
Uncaught TypeError: Assignment to constant variable.
(3)聲明後必須當即初始化
const PI; PI = 3.1415; console.log(PI);
報錯:
Uncaught SyntaxError: Missing initializer in const declaration
(4)不容許在相同做用域內重複聲明同一個變量的
const PI = 3.1415; console.log(PI); const PI = 3.1415926; console.log(PI);
報錯:
Uncaught SyntaxError: Identifier 'PI' has already been declared
正確的用法
const PI = 3.1415; var s= 3*3*PI; console.log(s);
輸出:
28.273500000000002
4.常見的面試題
var msg = ["This", "is", "a", "test"]; for (var i = 0; i < msg.length; i++) { console.log("outer:"+i); setTimeout(function() { console.log("index:" + i + ",msg:" + msg[i]); }, 0); }
輸出:
outer:0
outer:1
outer:2
outer:3
index:4,msg:undefined
index:4,msg:undefined
index:4,msg:undefined
index:4,msg:undefined
緣由:
setTimeout的執行方式是異步執行
JavaScript 是單線程的,遇到setTimeout後會另開一條線程
執行setTimeout裏的代碼時,同步代碼for循環已經執行完成
整個循環中只有一個i
,i
被for
循環以及三個回調函數共用,循環結束後i=4,已經超出了本來數組的範圍
把var 改爲let
var msg = ["This", "is", "a", "test"]; for (let i = 0; i < msg.length; i++) { console.log("outer:"+i); setTimeout(function() { console.log("index:" + i + ",msg:" + msg[i]); }, 0); }
輸出:
outer:0
outer:1
outer:2
outer:3
index:0,msg:This
index:1,msg:is
index:2,msg:a
index:3,msg:test
緣由:
let所聲明的變量,只在let
命令所在的代碼塊內有效,並且有暫時性死區的約束
暫時性死區:只要塊級做用域內存在let命令,它所聲明的變量就「綁定」(binding)這個區域, 再也不受外部的影響