高级js 变量提升以及自由变量
Q首先一道题
if(false){ var a = 1; } console.log(a); //undefined //我以为输出ReferenceError: aa is not defined //但是实际输出undefined //因为js没有块级作用域,所以最后代码就成了这样 var a; if(false){ a = 1; } console.log(a);
上面是一个引子 js没有块级作用域
《1》 let和const声明的变量只在let命令所在的代码块内有效
在代码块外引用let和const声明的变量 无效
// ReferenceError: i is not defined
《2》const let命令改变了语法行为,它所声明的变量一定要在声明后使用
原因是存在暂死区
if (true) { // TDZ开始 tmp = 'abc'; // ReferenceError console.log(tmp); // ReferenceError let tmp; // TDZ结束 console.log(tmp); // undefined tmp = 123; console.log(tmp); // 123 }
《3》不允许重复声明,同一块级作用域中
《4》const声明一个只读的常量。一旦声明,常量的值就不能改变
这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。
对于const来说,只声明不赋值,就会报错。
块级作用域解析
ES5 只有全局作用域和函数作用域,没有块级作用域,这带来很多不合理的场景
第一种场景,内层变量可能会覆盖外层变量。
第二种场景,用来计数的循环变量泄露为全局变量
ES6 中let 和const 带来了块级作用域(匿名立即执行函数不再那么必要)
块级作用域与函数声明
《1》ES5 规定,函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。
浏览器没有遵守这个规定,为了兼容以前的旧代码,还是支持在块级作用域之中声明函数
《2》ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
三条规则只对 ES6 的浏览器实现有效,其他环境的实现不用遵守,还是将块级作用域的函数声明当作let处理
- 允许在块级作用域内声明函数。
- 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
- 同时,函数声明还会提升到所在的块级作用域的头部
// 浏览器的 ES6 环境 function f() { console.log('I am outside!'); } (function () { var f = undefined; if (false) { function f() { console.log('I am inside!'); } } f(); }()); // Uncaught TypeError: f is not a function
// ES5 环境 function f() { console.log('I am outside!'); } (function () { function f() { console.log('I am inside!'); } if (false) { } f(); }()); // I am inside! // ES6 环境 function f() { console.log('I am outside!'); } (function () { function f() { console.log('I am inside!'); } if (false) { } f(); }()); // I am outside!
1.var 和function 的声明提升可以在函数内return 后面仍然见效(因为js预解析)
var a = 1; function b() { a = 120; return; function a() {} } b(); alert(a); //1; //实际 var a = 1; function b() { var a; //此处为函数 a = 120; return; function a() {} } b(); alert(a);
在创建这个函数的时候,这个函数的作用域就已经决定了,而是不是在调用的时候,
    本人是一个技术爱好者
1.但是每个技术爱好者都是从萌新开始的
2.我所有的博文都是我各方资料查阅(看的比较乱比较杂,因为有些是群里讨论等等来源,无法辨别出处,所以我的文章都是没有写明出处,都是我个人消化后整理,)
3.但是没有经过我实践的我一般会标注
4.希望大家共同交流共同进步,指出我的不足 谢谢
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号