1. 變量和常量
1.1 概念
我們先分清兩個概念:
變量:存儲數(shù)值的容器
常量:只讀的常量(一旦申明,不能改變)
變量不是數(shù)值本身,它們僅僅是一個用于存儲數(shù)值的容器。
1.2 定義
1.2.1 規(guī)則:
- 由字母數(shù)字下劃線和$組成
- 不能以數(shù)字開頭
- 嚴格區(qū)分大小寫
- 不能使用關鍵字和保留字
合法變量:
username
_age
_23
$23
不合法變量名:
class
4n
var
if
ES6保留字(Reserved keywords as of ECMAScript 2015)
| break | export | super | case | extends | switch |
| this | class | for | throw | const | function |
| if | typeof | debugger | import | var | default |
| in | void | delete | instanceof | while | do |
| new | with | else | return | yield |
保留字(Future reserved keywords)
| enum | await |
嚴格模式下保留字
| implements | package | public | interface | private | static | let | protected |
前標準(ES1-ES3)保留字
| abstract | float | synchronized | boolean | goto | throws |
| transient | char | long | volatile | double | native |
| final | short | null | true | false |
1.2.2 var
// 定義變量
var title = 'hello world';
// 定義多個變量
var username = 'Moddest', age = 29, sex = 'man';
1.2.3 let(ES6)
let title = 'hello world';
// 定義多個變量
let username = 'Moddest', age = 29, sex = 'man';
1.2.4 const(ES6):常量
const title = 'hello world';
// 定義多個常量
const username = 'Moddest', age = 29, sex = 'man';
1.3 注意
- const注意事項
const申明常量,一旦申明,無法改變。
但是。。。
const user = { name: 'Moddest' };
user.age = 20;
console.log(user.age); // 正確:20
user = { height: 175 }; // 錯誤:TypeError: "user" is read-only
究其本質(zhì):
const定義的常量值,如果是
? 簡單的數(shù)據(jù)類型(數(shù)值,布爾值,字符串):值保存在對應的內(nèi)存地址,不能改變
? 復合類型的數(shù)據(jù)(對象和數(shù)組):變量指向內(nèi)存地址,保存的是實際數(shù)據(jù)的指針,內(nèi)部值的改變不受影響
- var,let,const區(qū)別
1. 區(qū)別1:“變量提升”
var:存在變量提升
let:不存在變量提升
const:不存在變量提升
// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;
// let 的情況
console.log(bar); // 報錯ReferenceError
let bar = 2;
2. 區(qū)別2: “暫時性死區(qū)(temporal dead zone,簡稱 TDZ)”
if (true) {
// TDZ開始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結(jié)束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
typeof也不是百分百安全的操作哦(之前可以先typeof檢測,再用var定義變量)
目的:ES6 規(guī)定暫時性死區(qū)和let、const語句不出現(xiàn)變量提升,主要是為了減少運行時錯誤,防止在變量聲明前就使用這個變量,從而導致意料之外的行為
- 不允許重復申明
let a = 12;
let a = 34; // 報錯
-
為什么要用塊級作用域
第一種場景,內(nèi)層變量可能會覆蓋外層變量。
var tmp = new Date();
function f() {
console.log(tmp); // undefined
if (false) {
// 因為此處存在變量提升
var tmp = 'hello world';
}
}
f(); // undefined
? 第二種場景,用來計數(shù)的循環(huán)變量泄露為全局變量。
var s = 'hello';
// 改用let則避免i成為全局變量
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5