码迷,mamicode.com
首页 > 其他好文 > 详细

ES6学习(2)

时间:2019-11-06 23:01:40      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:ide   strong   运行时   开始   let   undefined   OLE   window下   实现   

块级作用域

  ES5中只有全局作用域和函数作用域,没有块级作用域,

 

 1 //内层变量可能覆盖外层变量
 2 
 3 var tmp = new Date();
 4 
 5 function f() {
 6   console.log(tmp);
 7   if (false) {
 8     var tmp = hello world;
 9   }
10 }
11 
12 f(); // undefined
13 
14 // 用来计算的循环变量泄漏为全局变量
15 var s = hello;
16 
17 for (var i = 0; i < s.length; i++) {
18   console.log(s[i]);
19 }
20 
21 console.log(i); // 5 

 

 

  ES6中let const 实际上为JavaScript新增了的块级作用域,如果使用let,上述f()就会报错, console.log(i)则会报错,i is not defined

 

  ES6 允许块级作用域的任意嵌套

1 {{{{
2   {let insane = Hello World}
3   console.log(insane); // 报错
4 }}}};
5 
6 {{{{
7   let insane = Hello World;
8   {let insane = Hello World}
9 }}}};

  

  块级作用域的出现,实际上使得广泛应用的匿名自执行函数表达式(匿名IIFE)不再必要

 1 // IIFE 写法
 2 (function () {
 3   var tmp = ...;
 4   ...
 5 }());
 6 
 7 // 块级作用域写法
 8 {
 9   let tmp = ...;
10   ...
11 }

 

块级作用域与函数声明

  ES5 中规定, 函数只能在顶层作用域和函数作用域之中声明, 不能在块级作用域声明,

  ES6引入块级作用域,明确运行在块级作用域中声明函数, ES6 规定块级作用域之中,函数声明语句的行为类似let,在块级作用域之外不可引用

 1 function f() { console.log(‘I am outside!‘); }
 2 
 3 (function () {
 4   if (false) {
 5     // 重复声明一次函数f
 6     function f() { console.log(‘I am inside!‘); }
 7   }
 8 
 9   f();
10 }());

 

  上面的代码在ES5中运行,会得到"I am inside!", 因为在if内声明的函数f会被提升到函数的头部

    而在ES6中就完全不一样了,因为块级作用域内声明的函数类似于let, 对于作用域之外没有影响, 但是运行一下上面的代码就会报错 

 1 // 浏览器的 ES6 环境
 2 function f() { console.log(‘I am outside!‘); }
 3 
 4 (function () {
 5   if (false) {
 6     // 重复声明一次函数f
 7     function f() { console.log(‘I am inside!‘); }
 8   }
 9 
10   f();
11 }());
12 // Uncaught TypeError: f is not a function

报错原因:

  因为如果改变了块级作用域内声明的函数的处理规则,那么对老代码会产生很大的影响,为了减轻因此产生的不兼容问题, ES6 中规定, 浏览器的实现可以不遵守上面的规定,而是有自己的行为方式,即:

  1\ 允许在块级作用域内声明函数, 2\ 函数声明类似var, 即会提升到全局作用域或函数作用域的头部, 3\ 勇士函数声明还会提升到所在块级作用域的头部

  注意 上面三条规则只对ES6的浏览器实现有线掐环境不遵守, 还是将块级作用域的函数声明当做let处理

由于环境导致的行为差异太大, 还是应该避免在作用域内声明函数, 如果确实需要的话, 也应该写成函数表达式

  还需要注意的是, ES6的块级作用域必须有大括号, 如果没有JavaScript就认为不存在块级作用域

1 // 第一种写法,报错
2 if (true) let x = 1;
3 
4 // 第二种写法,不报错
5 if (true) {
6   let x = 1;
7 }

 

 

顶层对象的属性

  顶层对象在浏览器环境指的是window对象,在Node中值得是global对象,ES5中, 顶层对象的属性与全局变量是等价的, 这样会造成很多问题, 首先没法在编译时就报出变量未声明的错误, 只有运行时才能知道,其次程序员也可能不知不觉创建了全局变量,最后顶层对象的属性到处可以读写,这非常不利于模块化编程

  ES6 为了改变这一点,一方面规定为了兼容性, var命令和function命令声明的全局变量,依旧是顶层对象的属性,另一方面规定, let命令, const命令, class命令声明的全局变量, 不属于顶层对象的属性, 也就是说ES6开始全局变量将逐步与顶层对象的属性脱钩

  

 1 var a = 1;
 2 // 如果在 Node 的 REPL 环境,可以写成 global.a
 3 // 或者采用通用方法,写成 this.a
 4 window.a // 1
 5 
 6 let b = 1;
 7 window.b // undefined
 8 
 9 //有var声明的全局变量a 也属于顶层对象的属性, 因此window下有a属性,
10 //全局变量b有let命令声明,所以他不是顶层对象属性, 返回undefined

ES6学习(2)

标签:ide   strong   运行时   开始   let   undefined   OLE   window下   实现   

原文地址:https://www.cnblogs.com/newttt/p/11808899.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!