开辟一个内存空间,给这个内存空间贴一个标签,标签即变量名,通过变量名,可以访问到该变量对应开辟的内存空间。

let

声明一个变量,可随时更改变量的值。

const

声明一个常量,声明后再不可改变变量的值。

var

类似 let ,老的JS中声明变量的唯一方式。

let,const 和 var的差异(重点)

  • let const块级作用域,而 var 没有。

    什么是块? 简单理解即 > {} 包裹的代码块。 ```javascript if(true){ var test = true } console.log(test) // 正常打印true

if(true) { let test = true } console.log(test) // 报错:test is not defined

  1. - **var**相比letconst,允许**重复声明**。
  2. - **var**声明的变量,可以再其声明语句之前被使用(**变量提升,hosting,但赋值停留原地**)。而**let, const具有暂时性死区**,会报错。
  3. > MDN的定义,在变量初始化前访问该变量会导致引用错误,该变量处在一个自块顶部到初始化处理的暂存死区中。
  4. ```javascript
  5. console.log(a)
  6. var a = 1;
  7. // 经过hosting相当于
  8. var a;
  9. console.log(a) // 打印undefined
  10. a = 1 // 赋值停留原地
  11. // 甚至这样也会提升,因为var无视代码块,会提升到当前函数作用域顶部
  12. function sayHi() {
  13. a = 'hello'
  14. if(false) { // 这个if代码块无效,var直接提升到sayHi函数最顶部
  15. var a;
  16. }
  17. console.log(a) // 打印hello
  18. }

暂时性死区和此法作用域的例子

  1. function foo() {
  2. var a = 1;
  3. if(a) {
  4. // 这里的let a劫持了if块,而a + 2中的a访问的是if块内的a,而不是外层的var a,
  5. // 在还未初始化时就访问,因此报错。
  6. let a = a + 2
  7. }
  8. }
  9. foo() // 报错,Cannot access 'a' before initialization。a初始化前不能访问

demo(经典)

经常会遇到的一道面试题,通常用于考察闭包的使用。如下展示借助块级作用域

  1. for(var i = 0; i < 10; i++) {
  2. setTimeout(() => {
  3. console.log(i)
  4. }, 1000)
  5. }
  6. // 打印10个10。
  7. // 原因在于 var 的没有块级作用域,1秒后,i值变为了10,10个定时器此时访问的是同一个i,因此打印10。
  8. // 使用let,劫持块级作用域
  9. for(let i = 0; i < 10; i ++) {// 同上} // 顺序打印0 到 9
  10. // 注意如果你把let i = 0 提到外面,则不行,因为没有劫持到每个循环的块。
  11. let i = 0;
  12. for(; i < 10; i ++) {// 同上} // 打印10个10。

IIFE

ES6前的时代,只有函数作用域和全局作用域,因此借助函数作用域模仿块级作用域,这种方式叫立即调用函数。

  1. function() {}() //报错,函数声明需要一个函数名
  2. function name() {}() // 报错,语法错误,JS不允许立即调用函数
  3. // 所以通过()将函数声明包裹,告诉JS,这是一个函数表达式可以直接调用。
  4. (function() {
  5. // 函数体
  6. })()
  7. // 所以上面的demo也可以借助IIFE来完成。
  8. for(var i = 0; i ++; i < 10) {
  9. setTimeout(
  10. (function d(i) {console.log(i)})(i), // 每个IIFE会访问创建时传入给自己的变量i,而不会访问到最外层的i
  11. 1000
  12. )
  13. }

变量命名

遵循驼峰变量命名,起一个有意义的名字,方便理解代码含义。

驼峰规则

let a = 'isMyBook' 除首字母外的单词的首字母大写。

常量命名

通常固定的,不会变值称为常量。通常是大写命名。 const PI = '3.14' 。当然通过计算出来的值,我们还是采用驼峰命名即可 const a = 1 + 2 ,因为并不是在计算机运算前就知道的,而 π 这个是世界公认的无需计算的值。