博客列表 >PartIII 01 ES6基础知识(0831mon)

PartIII 01 ES6基础知识(0831mon)

老黑
老黑原创
2020年09月02日 19:14:32745浏览

主要内容:

  1. 变量:变量本来是先声明,再赋值。但如果一次性以var a = 2这种方式,尤其是放在调用后面的话。ES6会默认为自动声明了,但无法调用后面的赋值,以undefined方式显示出来。

  2. 函数提升:函数的调用可以在函数声明定义前,也可以在后。

  3. 函数表达式不支持提升,调用必须在声明后面
  4. let变量导致的暂时性死亡(TDZ)
  5. 块作用域与变量外泄,及解决方案-立即调用函数IEEF
  6. 三种作用域(全局、函数、块)
  7. 常量大写全靠约定

1. ES6简介

ECMAScript 6.0(简称 ES6), 是 JavaScript 下一代标准

1-1. ECMAScript 与 JavaScript 的关系

  • ECMAScript 是浏览器脚本语言的标准
  • JavaScript 是 ECMAScript 标准的实现
  • 考虑到 JavaScript(简称 JS)是前端默认脚本语言,所以二者几乎同义

1-2. ES6 与 ECMAScript 2015 的关系

  • ECMAScript 2015 (简称 ES2015)
  • 2011 年, ECMAScript 5.1 发布后,即开始制定 JS 下一代标准,即 ES6
  • 2015 年 6 月,ES6 第一个版本发布,使用年份标记,正式名称为 ECMA2015
  • 所以, ES6 是泛指,包括 ES2015/ES2016/ES2017/ES2018…

1-3. Babel 转码器

  • 较古老的浏览器不能直接运行 ES6 代码,需要使用转码器将 ES6 语法转为 ES5
  • Babel 是使用广泛的转码器,安装指令:npm install --save-dev @babel/core
  • Babel 可以实现命令转码,浏览器转码, 在线转码等方式供选择

2. 变量提升

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>变量提升</title>
  7. </head>
  8. <body>
  9. <script>
  10. // 变量提升: 变量声明的提升
  11. // 在变量声明之前访问该变量,理论上应该报一个引用错误
  12. // 1. 变量声明被引擎自动提前到当前(全局)作用域的顶部
  13. var username;
  14. console.log(username);
  15. username = "Peter Zhu";
  16. console.log(username);
  17. // 1. 变量声明
  18. // var username;
  19. // console.log(username);
  20. // 2. 变量赋值/初始化
  21. // username = "Peter Zhu";
  22. // console.log(username);
  23. // 最常用是将变量的声明与初始化/赋值写到一起
  24. // 声明 + 初始化赋值
  25. var username = "Admin";
  26. function getValue() {
  27. // 2. 变量声明被引擎自动提前到当前(函数)作用域的顶部
  28. // 声明:被提前到当前作用域顶部
  29. var username;
  30. // 如果声明变量时未初始化,那么会自动用undefined赋值
  31. // var username = undefined;
  32. // 函数内私有变量的赋值
  33. console.log(username);
  34. username = "Tony老师";
  35. console.log(username);
  36. }
  37. getValue();
  38. // 变量提升让变量的生命周期(从声明到回收)变得不可控
  39. // 使用es6: 块级作用域 , 同义词: 词法作用域, 静态作用域
  40. </script>
  41. </body>
  42. </html>

3. 函数提升

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>函数提升</title>
  7. </head>
  8. <body>
  9. <script>
  10. // 函数声明: 会自动提前到当前作用域的顶部
  11. function demo1() {
  12. console.log("function demo1()");
  13. }
  14. // 函数调用
  15. demo1();
  16. // 函数允许重复声明,后面声明会覆盖到前面的
  17. function demo1() {
  18. console.log("重复声明了demo()");
  19. }
  20. // js中的函数不能重载:函数名称相同,通过不同的参数具有不同的行为
  21. // 变量也允许重复声明
  22. // var email = "a@php.cn";
  23. // console.log(email);
  24. // var email = "b@php.cn";
  25. // console.log(email);
  26. // 作用域: 全局作用域, 函数作用域
  27. // 在函数作用域中,仍然支持函数声明提前
  28. function outer() {
  29. // 子函数调用
  30. inner();
  31. // 子函数声明: 也会声明提前
  32. function inner() {
  33. console.log("我是outer()中的子函数inner()");
  34. }
  35. }
  36. // 函数表示式(变量函数的声明不会被提升)
  37. // console.log(myemail());
  38. // 全局函数
  39. var myemail = function () {
  40. return "function email()";
  41. };
  42. // 全局变量
  43. var myemail = "admin888@php.cn";
  44. console.log(myemail);
  45. outer();
  46. </script>
  47. </body>
  48. </html>

4. 函数表达式

  • 函数表达式不能进行提升,也就是说必须调用在声明的后面
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>函数表达式</title>
  7. </head>
  8. <body>
  9. <script>
  10. // 1. 全局不存在函数表达式声明提升
  11. // demo1(); // 调用失败
  12. var demo1 = function () {
  13. console.log("Hello demo1()");
  14. };
  15. demo1(); // 调用成功
  16. // 2. 函数声明与函数表达式: 同名共存,哪个优先,声明优先(声明提升)
  17. demo2();
  18. // 函数声明
  19. function demo2() {
  20. console.log("hello 声明demo2()");
  21. }
  22. // 函数表达式
  23. var demo2 = function () {
  24. console.log("hello 表达式demo()");
  25. };
  26. // demo2();
  27. // 3. 函数内部
  28. var demo3 = function () {
  29. // demo4();
  30. // 函数内部也不存在函数表达式声明提升
  31. var demo4 = function () {
  32. console.log("demo3内部的demo4()");
  33. };
  34. demo4();
  35. };
  36. demo3();
  37. </script>
  38. </body>
  39. </html>

5. 暂时性死亡(TDZ)

  • let 支持块作用域, if(){…}
  • let 不支持声明提升
  • 所有在let声明之前会产生一暂时性的使用上的死区,直接到遇到let声明
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>暂时性死区(TDZ)</title>
  7. </head>
  8. <body>
  9. <script>
  10. var num;
  11. var num = 10;
  12. if (true) {
  13. // num = 10,为什么?因为当前的代码块if()没有num声明,所以就引用了外部
  14. console.log("num =" + num);
  15. }
  16. if (true) {
  17. // let 支持块作用域,if(){...}
  18. // let 不支持声明提升
  19. // 所有在let声明之前会产生一暂时性的使用上的死区,直接到遇到let声明
  20. console.log("num = " + num);
  21. // 不用var , 用let
  22. let num = 88;
  23. }
  24. </script>
  25. </body>
  26. </html>

6. 块作用域与变量泄露

  • 解决方案: 立即调用函数IFFE
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>无块作用域会产生什么样的问题</title>
  7. </head>
  8. <body>
  9. <script>
  10. // 块作用域
  11. // 1. 变量泄露
  12. function show1(count) {
  13. for (var i = 0; i < count; i++) {
  14. console.log(i);
  15. }
  16. // for()代码块,js不支持块作用域,所以块中的变量 i 泄露到外部
  17. console.log("i = ", i);
  18. }
  19. // show1()等价语法
  20. function show2(count) {
  21. // 变量提升
  22. var i;
  23. for (i = 0; i < count; i++) {
  24. console.log(i);
  25. }
  26. // for()代码块,js不支持块作用域,所以块中的变量 i 泄露到外部
  27. var i = 20;
  28. console.log("i = ", i);
  29. }
  30. show2(5);
  31. // 解决方案: 立即调用函数IFFE
  32. // (function (a, b) {
  33. // console.log(a + b);
  34. // })(10, 20);
  35. // (函数声明)(函数调用参数);
  36. function show3(count) {
  37. // 使用立即执行函数来解决块中变量泄露的问题
  38. (function () {
  39. for (var i = 0; i < count; i++) {
  40. console.log(i);
  41. }
  42. })(5);
  43. // 使用IIFE创建了一个临时的函数作用域,所以外部已经访问不到这个i
  44. console.log("i = ", i);
  45. }
  46. show3();
  47. </script>
  48. </body>
  49. </html>

7. 作用域

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>作用域</title>
  7. </head>
  8. <body>
  9. <script>
  10. // 作用域: 1.全局 2. 函数 3. 块
  11. // 1. 全局作用域:函数和代码块之外的代码
  12. // 全局变量
  13. var username = "peter zhu";
  14. console.log(username);
  15. // 2. 函数作用域
  16. function demo1(username) {
  17. return username;
  18. }
  19. console.log(demo1("admin"));
  20. // 3. 块作用域
  21. if (true) {
  22. var email = "admin@php.cn";
  23. // 块内部可以访问
  24. console.log(email);
  25. }
  26. // 块外部也可以访问
  27. console.log(email);
  28. // 使用立即执行函数创建一个块作用域
  29. // IIFE来模拟一个块作用域
  30. (function () {
  31. if (true) {
  32. var color = "red";
  33. console.log("innner ", color);
  34. }
  35. })();
  36. // 块外部不能再访问
  37. console.log(color);
  38. </script>
  39. </body>
  40. </html>

8. 几点注意

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>var声明的问题</title>
  7. </head>
  8. <body>
  9. <ul>
  10. <li>item1</li>
  11. <li>item2</li>
  12. <li>item3</li>
  13. <li>item4</li>
  14. <li>item5</li>
  15. </ul>
  16. <script>
  17. // 1. 允许重复声明
  18. var price = 100;
  19. var price = 200;
  20. console.log(price);
  21. // 2. 存在变量提升
  22. var color;
  23. console.log(color);
  24. // var color = "blue";
  25. color = "blue";
  26. console.log(color);
  27. // 变量声明也会发生在函数作用域内
  28. // 3. 不支持块作用域
  29. if (true) {
  30. var email = "peter@qq.com";
  31. }
  32. console.log(email);
  33. var lis = document.querySelectorAll("li");
  34. for (var i = 0; i < lis.length; i++) {
  35. // 通过立即执行函数将块包裹起来,来模拟一个块作用域
  36. (function (i) {
  37. lis[i].addEventListener("click", function () {
  38. console.log("点击了第", i + 1, " 个");
  39. });
  40. })(i);
  41. }
  42. // 4. 常量全靠约定
  43. var APP_NAME = "客户管理系统";
  44. // 相信大家都是好人,都是君子,看到全大写的变量名, 就主动不去更新它
  45. var APP_NAME = "学生管理系统";
  46. console.log(APP_NAME);
  47. </script>
  48. </body>
  49. </html>
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议