JS深入理解—研究JS变量声明和函数声明提升

还是从一个例子研究起,如下代码将会输出什么结果呢?

sayHello();
function sayHello() {
    console.log(name);
    console.log(gender);
    var name = 'yulsh';
    let gender = '男';
}

输出的结果是:

undefined
Uncaught ReferenceError: Cannot access 'gender' before initialization

在 javascript 中变量的声明会提升,因此上面的代码真正运行的过程是这样的:

var name;  // 变量声明前置,初始化默认值 undefined
let gender; // 变量声明前置,没有被初始化
console.log(name);
console.log(gender);
name = 'yulsh';
gender = '男';

似乎忽略了一点,sayHello 在最上面也可以执行 ? 因为,函数声明的提升更加彻底,并且优先级高于变量

通过上面的说明,应该可以理解为什么是上面的输出结果了吧?

变量赋值的三个阶段

  1. 创建变量,在内存中开辟内存空间;
  2. 初始化变量,将变量初始化为 undefined
  3. 变量赋值;

关于 var, let (const类似) , function 的差异:

  1. var 的 [创建] 和 [初始化] 都被提升了;
  2. let 的 [创建] 过程被提升了;
  3. function 的 [创建] [初始化] [赋值] 过程都被提升了;// sayHello 能运行的原因

验证let存在变量提升

ES6中 使用 let, const 来声明变量,为了验证上面的结论,且看看下面的例子:

let name = 'zhagnsan';
{
	console.log(name);
	let name = 'yulsh';
}

输出的结果:

Uncaught ReferenceError: Cannot access 'name' before initialization

{...} 中的 let 是被提升了,执行的过程应该是这样的:

let name = 'zhagnsan';
{
	let name; // 没有被初始化
	console.log(name);
	name = 'yulsh';
}

使用 let / const 声明的变量是具有块作用域的,因此,变量声明的时候在 { } 内部做了提升,但是没有初始化。这个过程产生了另外一个概念 暂时性死区。有一篇文章详细的讨论了TDZ

再看一个例子

下面的代码将会输出怎样的结果呢? 看起来很迷惑,通过理解它,我们就可以彻底的理解变量提升和函数提升了。


console.log(a); 
var a = 1;
console.log(a);    
function a() { console.log(2); }
console.log(a);   
var a = 3;
console.log(a);    
function a() { console.log(3); }
a();
console.log(a);

输出:

ƒ a() { console.log(3); }
1
1
3
Uncaught TypeError: a is not a function

实际的执行过程是这样的:

function a() { console.log(3); } // 遇到多个同名的变量或者函数,以最后一个为准,并且函数提升的优先级高
console.log(a); // 输出 函数体
var a = 1;  // 函数a被赋值为1, 从函数变成了变量
console.log(a); // 输出 1
console.log(a); // 输出 1
var a = 3;  // 变量赋值为 3
console.log(a); // 输出 3
a(); // 执行出错,a已经不是函数,不能继续执行
console.log(a); // 不会执行

总结

浏览器引擎在运行js过程中,大致分为两个步骤,一是解析js,把变量/函数等在对应的作用域内做提升;二是执行JS。掌握了变量和函数的提升,才能对js执行过程了如指掌。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值