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);