JavaScript 进阶问题列表

1. 下面的代码输出的是什么

1
2
3
4
5
6
7
8
var name = "test name";
function testVariables() {
console.log(name);
console.log(age);
var name = "NyanShen"
let age = 27
}
testVariables();

在函数中,我们首先使用var关键字声明了name变量。这意味着变量在创建阶段会被提升(javascript会在创建变量创建阶段为其分配内存空间),默认值为undefined的值.

使用let关键字(和const)声明的变量也会存在变量提升,但与var不同,初始化没有被提升。在我们声明(初始化)它们之前,它们是不可被访问的。这被称为“暂时死区”。当我们在声明变量之前尝试访问变量是,javascript会抛出一个ReferenceError

关于let的是否存在变量提升,我们可以用下面例子来验证:

1
2
3
4
5
let name = "Nyan Test";
{
console.log(name);
let name = "Nyan";
}

let变量如果不存在变量提升,那么console.log(name)就会打印出Nyan Test,结果去抛出了ReferenceError,那么这很好的说明了let也存在变量提升,但是它存在一个“暂时死区”,在变量未初始化或未赋值时不允许访问。

要理解提升的定义,还需要搞懂js变量的执行过程

js变量的执行过程包括

1
创建 =》初始化 =》 赋值

var 声明的变量执行过程

1
找到当前作用域中所有var声明的变量,创建变量 =》初始化为 undefined =》**执行代码** =》 赋值

function 声明的变量执行过程

1
找到当前作用域中所有function声明的变量,创建变量 =》初始化 =》赋值 =》**执行代码**

let 声明的变量执行过程

1
找到当前作用域中所有let声明的变量,创建变量 =》**执行代码** =》初始化为let声明的值,没有就为undefined  =》 赋值(修改值)

const 声明的变量执行过程

1
找到当前作用域中所有let声明的变量,创建变量 =》**执行代码** =》初始化为let声明的值,没有就为undefined

有没有被提升,主要看代码执行的时机

  • let 的「创建」过程被提升了,但是初始化没有提升。
  • var 的「创建」和「初始化」都被提升了。
  • function 的「创建」「初始化」和「赋值」都被提升了。