JavaScript作用域之完全理解

JavaScript的作用域一直如一滩浑水一般,包括工作多年的人也不能完全理解它的机制,很多人简单的概括为function内部以及不带function函数中不带有var声明的为局部变量,function外部为全局变量,其实这种看法是一种经验上的区分,所以,本文就是详细的介绍作用域的机制,以及为什么会出现上述这样的情况,帮助各位更好的理解,做到一通百通。

先看如下代码示例:

function a(){

var a=10;

}

a();

console.log(a);

这个非常容易识别,就像之前说的,a属于局部变量,外部不可访问,console.log()输出的结果是a函数体,并非10,因为 var a=10这部分代码是无法被外部访问,我们可以认为是锁死在了函数体内部。

那么再来一个变种:

function a(){

a=10;

}

a();

console.log(a);

这个对于有相当工作经验的人来说,也容易识别,console.log输出的结果是10,但这和第一段代码有明显的区别,a作为全局变量被抛出外部了,代码在执行过程中其实是先把函数体进行了声明提前,之后a(),调用函数的时候,执行函数体内部代码,因为a没有通过var声明,并没有锁死在函数体内部,而是被抛出到外部执行了,就造成了a变量的覆盖,此时输出结果应该是10

我们继续变种:

function a(a){

var a=10;

}

a(20);

console.log(a);

这段代码执行结果是什么?函数体?10?20?在这个变种里面,有3个a,从这里的变种开始,变得有些迷惑了,要搞清楚,要看程序执行的内存图,下图会进行说明:

 

所以,判断作用域,不能简单的通过变量存在于函数体内部或者外部进行判断,更要深层次的去看到代码在计算机内存中的运行过程,这个例子中,如果有a被抛出到全局,那么在栈空间中,会覆盖掉原本的a值,a在栈空间是无法保存引用类型的值,只能通过16进制数到堆空间进行查找,函数的形参,其实也是声明在函数体内部的变量,但是其优先级要大于在函数体内声明的变量,之所以函数中的变量和全局变量不冲突的根本原因在于,在内存图中,所存储的不在一个空间,通过内存图能够更加清晰的完全理解JavaScript中的作用域,所以console.log()出来的结果是函数体本身。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值