1.let命令
1-1. ++牢記重點(diǎn)++
let聲明變量只在所在塊級(jí)作用域起作用即{}
不存在變量提升即無(wú)聲明提前
在let聲明某個(gè)變量的前面拐邪,都屬于這個(gè)變量的死區(qū)
let聲明塊狀區(qū)域內(nèi)不允許重復(fù)聲明
1-2.++重點(diǎn)案列解釋++
(1).{
let a = 10;
var b = 1;
}
a // ReferenceError: a is not defined.
b // 1
- es5 沒(méi)有塊級(jí)作用域所以var聲明不報(bào)錯(cuò)而es6{}為塊級(jí)作用域外面不能訪(fǎng)問(wèn)里面
(2).for (let i = 0; i < 10; i++) {
// ...
}
console.log(i);
// ReferenceError: i is not defined
- for循環(huán)的計(jì)數(shù)器,就很合適使用let命令虚婿。計(jì)數(shù)器i只在for循環(huán)體內(nèi)有效屋剑,在循環(huán)體外引用就會(huì)報(bào)錯(cuò)
(3).var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a6; // 10
- 最終輸出10因?yàn)閕是全局變量 要等f(wàn)or循環(huán)全部執(zhí)行完畢在執(zhí)行函數(shù)a6而i的最終值為10
(4)var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a6; // 6
- 變量i是let聲明的茵臭,當(dāng)前的i只在本輪循環(huán)有效震叮,所以每一次循環(huán)的i其實(shí)都是一個(gè)新的變量胧砰,所以最后輸出的是6。你可能會(huì)問(wèn)苇瓣,如果每一輪循環(huán)的變量i都是重新聲明的朴则,那它怎么知道上一輪循環(huán)的值,從而計(jì)算出本輪循環(huán)的值钓简?這是因?yàn)?JavaScript 引擎內(nèi)部會(huì)記住上一輪循環(huán)的值,初始化本輪的變量i時(shí)汹想,就在上一輪循環(huán)的基礎(chǔ)上進(jìn)行計(jì)算外邓。
(5).for (let i = 0; i < 3; i++) {
let i = 'abc';
console.log(i);
}
// abc
// abc
// abc
- for循環(huán)還有一個(gè)特別之處,就是設(shè)置循環(huán)變量的那部分是一個(gè)父作用域古掏,而循環(huán)體內(nèi)部是一個(gè)單獨(dú)的子作用域损话。這表明函數(shù)內(nèi)部的變量i與循環(huán)變量i不在同一個(gè)作用域,有各自單獨(dú)的作用域。
(6).// var 的情況
console.log(foo); // 輸出undefined
var foo = 2;
// let 的情況
console.log(bar); // 報(bào)錯(cuò)ReferenceError
let bar = 2;
- 不存在變量提升
if (true) {
// TDZ開(kāi)始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結(jié)束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
- let前面都是死區(qū)
typeof x; // ReferenceError
let x;
typeof undeclared_variable // "undefined"
- tyoeof 檢驗(yàn)不安全會(huì)報(bào)錯(cuò)
// 報(bào)錯(cuò)
function () {
let a = 10;
var a = 1;
}
// 報(bào)錯(cuò)
function () {
let a = 10;
let a = 1;
}
function func(arg) {
let arg; // 報(bào)錯(cuò)
}
function func(arg) {
{
let arg; // 不報(bào)錯(cuò)
}
}
- 不允許重復(fù)聲明
2.塊級(jí)作用域
++2-1.為什么需要塊級(jí)作用域丧枪?++
- 內(nèi)層變量可能會(huì)覆蓋外層變量
var tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefinedvar tmp = new Date();
function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}
f(); // undefined
- 用來(lái)計(jì)數(shù)的循環(huán)變量泄露為全局變量
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5
++2-2.es5模仿塊級(jí)作用域++
(function () {
var tmp = ...;
...
}());
++2-3. es6塊級(jí)作用域++
{
let tmp = ...;
...
}
++2-4.塊級(jí)作用域的弊端---無(wú)法取到里面的值++
{
let t = f();
t = t * t + 1;
}
- 塊級(jí)作用域?qū)蓚€(gè)語(yǔ)句封裝在一起光涂。但是,在塊級(jí)作用域以外拧烦,沒(méi)有辦法得到t的值忘闻,因?yàn)閴K級(jí)作用域不返回值,除非t是全局變量
let x = do {
let t = f();
t * t + 1;
};
- 使得塊級(jí)作用域可以變?yōu)楸磉_(dá)式恋博,也就是說(shuō)可以返回值齐佳,辦法就是在塊級(jí)作用域之前加上do,使它變?yōu)閐o表達(dá)式變量x會(huì)得到整個(gè)塊級(jí)作用域的返回值
3.const命令
++const聲明一個(gè)只讀的常量债沮。一旦聲明炼吴,常量的值就不能改變。++
(1)const PI = 3.1415;
PI // 3.1415
PI = 3;
// TypeError: Assignment to constant variable.
- const聲明的變量不得改變值疫衩,這意味著硅蹦,const一旦聲明變量,就必須立即初始化闷煤,不能留到以后賦值
- 只聲明不賦值童芹,就會(huì)報(bào)錯(cuò)
- const的作用域與let命令相同:只在聲明所在的塊級(jí)作用域內(nèi)有效。
- const命令聲明的常量也是不提升曹傀,同樣存在暫時(shí)性死區(qū)辐脖,只能在聲明的位置后面使用。
(2)var message = "Hello!";
let age = 25;
// 以下兩行都會(huì)報(bào)錯(cuò)
const message = "Goodbye!";
const age = 30;
- const聲明的常量皆愉,也與let一樣不可重復(fù)聲明嗜价。
4.global對(duì)象
- 瀏覽器里面,頂層對(duì)象是window幕庐,但 Node 和 Web Worker 沒(méi)有window久锥。
- 瀏覽器和 Web Worker 里面,self也指向頂層對(duì)象异剥,但是 Node 沒(méi)有self瑟由。
- Node 里面,頂層對(duì)象是global冤寿,但其他環(huán)境都不支持歹苦。