==================== 概述:====================== 1. ECMASCript, Javascript, Node.js 它们的区别是什么? ECMASCript: 简称ES, 是一个语言标准(循环, 判断, 变量, 数组等数据类型) JavaScript: 运行在浏览器端的语言, 该语言使用ES标准。 ES + web api = Javascript NodeJs: 运行在服务端语言, 该语言使用ES标准。 ES + node api = NodeJs 无论是JavaScript,还是NodeJS, 他们都是ES的超集(super set) 2. ECMAScript有哪些关键版本? ES3.0: 1999 ES5.0: 2009 ES6.0: 2015, 从该版本开始, 不再使用数字作为变化, 而使用年份 ES7.0: 2016 3. ECMAScript6(es6)为啥那么重要? ES6是一个前端必会的技术, ES6解决了JS无法开发大型语言层面的问题。 ==================声明变量==================== 声明变量的问题: 使用var声明变量, 1. 允许重复变量的变量声明:导致数据的覆盖 var a= 1; function print(){ console.log(a) } 假设这里有1000行代码 var a =2; print(); 2. 变量提升: 怪异的数据访问,闭包问题 // 变量提升 if(Math.random() < 0.5){ var a = "abc"; console.log(a); }else{ console.log(a); } console.log(a); 变成下面的代码,由于变量提升 var a; if(Math.random() < 0.5){ a = "abc"; console.log(a); }else{ console.log(a); } console.log(a); // 闭包问题 例如: 在页面动态添加10个按钮, 然后点击按钮, 输出按钮的名字 var div = document.getElementById("divButtons"); 页面上有一个带div的盒子 for(var i = 0; i < 10; i ++){ var btn = document.createElement("button"); btn.innerHTML = " 按钮"+ i; div.appendChild(btn); // 按钮生成完毕, 等待点击, 获取里面的值 btn.onclick = function(){ console.log(i) // 结果i都是11, 因为闭包, 变量提升 } 修改方法: (function(i){ btn.onclick = function(){ console.log(i) // 结果就对了 } })(i) } 3. 全家变量挂载到全局对象: 全局对象成员污染问题 var abc = 123; console.log(window.abc) 结果是 123, 每次定义一个值,window都会加一个, 会全局污染 ===============es6使用let解决上面的问题===================== // 使用let来解决声明变量存在的问题,并且同时引入了块级作用域(代码遇到花括号,自动会创建一个作用域,块级作用域执行完了,会自动销毁, 块级作用域外不可以访问块级作用域里面的变量) let a = 123, console.log(window.a) // undefined 不会放到全局了 // let 声明的变量,不会挂载到全局了 // let 在同一个作用域里面, 只能有一个名字的, 不可以重复声明变量 // 使用let, 不会有变量提升, 因此不能在let定义变量之前使用它, // 底层实现的let声明的变量也会有提升, 但是提升后会放入到“暂时性死区”, // 如果访问暂时式性死区的变量,会报错,。 当代码运行到变量的声明语句时候,变量会从“暂时性死区”里面移除 // 在循环中,let声明变量的循环变量,会特殊处理,每次进入循环体, 都会开启一个新的作用域,并且将循环变量绑定到该作用域(每次循环会开启一个新的作用域),在循环结束后变量会销毁 例如: 在页面动态添加10个按钮, 然后点击按钮, 输出按钮的名字 let div = document.getElementById("divButtons"); 页面上有一个带div的盒子 for(let i = 0; i < 10; i ++){ let btn = document.createElement("button"); btn.innerHTML = " 按钮"+ i; div.appendChild(btn); // 按钮生成完毕, 等待点击, 获取里面的值 btn.onclick = function(){ console.log(i) // 结果就是i } } =====================使用const声明变量========================= const与let声明变量完全相同, 唯一区别: 仅在于用const声明的变量, 必须声明变量赋值, 而且不可以重新赋值。 在开发中,尽量使用const来赋值, 以保证变量的值不会被随意改变 原因如下: 1. 根据经验,在开发过程中,许多定义的变量,都不会改变,如div变量 2. 后续的很多框架,或者第三JS库, 都要求数据不可变,使用常量可以在一定程度上保证 注意:1. 常量不可以变,是指声明的常量的内存空间不可以变, 并不保证内容空间中的地址 指向的其他空间不变,如: 常量声明一个对象, 对象里面的值可以变 2. 常量的命名: 1. 特殊的常量: 从常量的字面意义上,一定是不可以变的,比如圆周率, 月底距离或其他绝不可能变化的配置, 一般常量的名称全部大写,多个单词用下划线分隔 2. 普通的常量: 使用和之前的命名即可, 小驼峰命名方法 3. 在for(let i; i < 10, i++)循环变量中,不可以使用常量, 但是在for in 循环里面可以使用