1.let和const不存在变量提升机制
创建变量的六种方式中:var/function有变量提升,而let/const/class/import都不存在这个机制
2.var允许重复声明,而let是不允许的
在相同的作用域中(或执行上下文中)
- 如果使用var/function关键词声明变量并且重复声明,是不会有影响的(声明第一次之后,之后再遇到就不再重复声明了)
- 但是使用let/const就不行,浏览器会校验当前作用域中是否已经存在这个变量了,如果已经存在了,则再次基于let等重新声明就会报错
// => 在浏览器开辟栈内存供代码自上而下执行之前,不仅有变量提升的操作,还有很多其它的操作 => “词法解析”或者“词法检测”:就是检测当前即将要执行的代码是否会出现“语法错误 SyntaxError”,如果出现错误,代码将不会再执行(第一行都不会执行)
console.log(1); // => 这行代码就已经不会再被执行了
let a = 12;
console.log(a);
let a = 13; // => Uncaught SyntaxError: Identifier 'a' has already been declared
console.log(a);
// => 所谓重复是:不管之前通过什么办法,只要当前栈内存中存在了这个变量,我们使用let/const等重复再声明这个变量就是语法错误
console.log(a);
var a = 12;
let a = 13; // => Uncaught SyntaxError: Identifier 'a' has already been declared
console.log(a);
3.let能解决typeof检测时出现的暂时性死区问题(LET比VAR更严谨)
http://es6.ruanyifeng.com/#docs/let
console.log(a); // => Uncaught ReferenceError: a is not defined
// 在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”
console.log(typeof a); // => "undefined" 这是浏览器的BUG,本应该是报错的,因为没有a(暂时性死区)
console.log(typeof a); // => Uncaught ReferenceError: Cannot access 'a' before initialization
let a;
if判断中的变量提升
// [PROPERTY] in [OBJECT] 验证当前属性是否属于这个对象 hasOwnProperty?
let obj = {
name: '吴振宇',
age: 21,
GF: null
};
console.log("name" in obj); // => TRUE
console.log("GF" in obj); // => TRUE
console.log("BF" in obj); // => FALSE
// -----------------------------------------------------
/*
* 全局作用域
* 1.变量提升
* 不管条件是否成立都要进行变量提升
* var a; // => 创建一个全局变量a => window.a
* 2.代码执行
*/
console.log(a); // => undefined
if (!('a' in window)) { // => 'a' in window => TRUE
var a = 13;
}
console.log(a); // => undefined
// 变体
console.log(a); // 报错
if (!('a' in window)) {
let a = 13; // a 是块级作用域的变量,外面不能使用
console.log(a) // 13
}
console.log(a); // 报错
// -----------------------------------------------------
/*
* 全局作用域
* 1.变量提升
* 但是做函数的有特殊性:在老版本浏览器中,确实不论条件是否成立,函数也是提前声明或者定义的,但是新版本浏览器中,为了兼容ES6严谨的语法规范,条件中的函数在变量提升阶段只能提前声明,不能提前定义
* function fn;
* 2.代码执行
*/
// 这个不作为重点
console.log(fn); // => undefined
// fn(); // => Uncaught TypeError: fn is not a function
if ('fn' in window) { // => TRUE
// 条件成立,进来后的第一件事是给FN赋值,然后在代码执行
fn(); // => "哈哈哈"
function fn() {
console.log('哈哈哈');
}
}
fn(); // => "哈哈哈"
// -----------------------------------------------------
/*
* 全局作用域
* 1.变量提升
* 2.代码执行
*/
f = function () {return true;} // => window.f=...
g = function () {return false;}
~function () {
/*
* 函数执行会形成一个私有作用域
* 1.变量提升 function g,只声明,不赋值,默认值是undefined
* 2.代码执行
*/
if (g() && [] == ![]) { // => Uncaught TypeError: g is not a function
f = function () {return false;}
function g() {return true;}
}
}();
console.log(f());
console.log(g());
// --------------------------------
// => 自执行函数:前面加的()或者!、-、~、+只有一个目的,让语法符合而已
// => 自执行函数本身不进行变量提升(没名字)
(function(n){})(10);
~function(n){}(10);
-function(n){}(10);
!function(n){}(10);
+function(n){}(10);