let
- 作用域
{
let a = 1;
var b = 2;
}
console.log(a); //Uncaught ReferenceError: a is not defined
let 聲明的變量只在所生命的代碼塊內(nèi)生效
var a = [];
for(var i=0; i<10; i++){
a[i] = function(){
console.log(i)
}
}
a[6]() = 10
var a = [];
for(let i=0; i<10; i++){
a[i] = function(){
console.log(i)
}
}
a[6]() = 6
- 不存在變量提升
console.log(a); // undefined var存在變量提升
var a = 1;
console.log(b); // b is not defined
let b = 2;
- 暫時(shí)性死區(qū)
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
//如果區(qū)塊中存在let和const命令,這個(gè)區(qū)塊對(duì)這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會(huì)報(bào)錯(cuò)。
- 不允許重復(fù)聲明
let不允許在相同作用域內(nèi),重復(fù)聲明同一個(gè)變量。
// 報(bào)錯(cuò)
function func() {
let a = 10;
var a = 1;
}
// 報(bào)錯(cuò)
function func() {
let a = 10;
let a = 1;
}
function func(arg) {
let arg; // 報(bào)錯(cuò)
}
function func(arg) {
{
let arg; // 不報(bào)錯(cuò)
}
}
為什么需要塊級(jí)作用域
// 內(nèi)層變量可能會(huì)覆蓋外層變量
var 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
const
const聲明一個(gè)只讀的常量。一旦聲明,常量的值就不能改變。
const一旦聲明變量,就必須立即初始化,不能留到以后賦值。
const PI = 3.1415926
- 作用域
// const的作用域與let命令相同:只在聲明所在的塊級(jí)作用域內(nèi)有效。
if (true) {
const MAX = 5;
}
MAX // Uncaught ReferenceError: MAX is not defined
- 暫時(shí)性死區(qū)
if (true) {
console.log(MAX); // ReferenceError
const MAX = 5;
}
- 不可重復(fù)聲明
let age = 25;
// 以下兩行都會(huì)報(bào)錯(cuò)
const message = "Goodbye!";
const age = 30;
- 不存在變量提升
console.log(PI)
const PI = 3.1415926 //PI is not defined
const本質(zhì)
const a = 1;
a = 2; // error
const obj = {};
obj.a = 1; //true
// const只能凍結(jié)對(duì)象指向地址,如果需要凍結(jié)對(duì)象,可以使用如下凍結(jié)函數(shù)。
var constantize = (obj) => {
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) => {
if ( typeof obj[key] === 'object' ) {
constantize( obj[key] );
}
});
};
頂層對(duì)象屬性
var命令和function命令聲明的全局變量,依舊是頂層對(duì)象的屬性
var a = 1;
window.a = 1;
function b(){}
window.b = function
let命令、const命令、class命令聲明的全局變量,不屬于頂層對(duì)象的屬性
let a = 1;
window.a // undefined
函數(shù)里面的this,如果函數(shù)不是作為對(duì)象的方法運(yùn)行,而是單純作為函數(shù)運(yùn)行,this會(huì)指向頂層對(duì)象。
function test(){
console.log(this)
}
test() // window.test()
VM341:2 Window {postMessage: ?, blur: ?, focus: ?, close: ?, parent: Window, …}
var t = new test()
VM341:2 test {} //this指向 t