JavaScript作用域

JavaScript作用域

1. 全局作用域

一般来说,以下三种情况下的变量拥有全局作用域。

(1)最外层的函数以及最外层声明的变量,例如:
var globalVar="variable"; //具有全局作用域的变量
//具有全局作用域的函数
function golbalFun(){
console.log("I am a global function");
}
(2)所有未声明直接赋值的变量拥有全局作用域,例如:
function(){
    var localVar="localVar"; //不拥有全局作用域
    globalVar="globalVal";  //拥有全局作用域
}
(3)所有window对象的属性拥有全局作用域,例如:

一般情况下,window对象的内置属性都拥有全局作用域,例如window.name、window.location、window.top等等。

2. 局部作用域

在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部属性包含了函数被创建的作用域中对象的集合,这个集合被称为函数的作用域链,它决定了哪些数据能被函数访问。

3.JavaScript的内存空间

JavaScript的内存空间分为栈空间和堆空间。通常来说,值类型(Number、Bool、null、undefined)存在栈空间内,引用类型(对象、数组、函数)存在堆空间内。如下图:
js内存空间示意图
这里注意:函数存在堆空间中是以字符串的形式,函数执行时再解析为函数代码。例如以下代码:

function test()
{
    console.log(test);
}
console.log(test);
//输出结果为:
test(){console.log(test);}
4. javascript查找上级作用域

看当前函数是在哪个作用域下定义的,那么他的作用域就是谁,与函数执行环境无关
看如下代码:

var num = 120;
function fn(){
    var num = 12;
    return function(){
        console.log(num);
    }
}
var f = fn();
f();

执行结果是 12
原理如图:
这里写图片描述

5. 一道 js 作用域面试题
function fn(){
    var i=10;
    return function(n){
        console.log(n+ (++i));
    }
}
var f = fn();
f(10);
f(20);
fn()(10);
fn()(20);

分析:
(1)f(10) 为21很简单,f(10)产生的函数作用域内没有 i 变量,上溯到 fn() 运行时产生的作用域内找到 i ,使 i 自增,10 + 11 = 21;
(2)f(20) ,由于 f=fn(),导致fn()运行时产生的作用域不会被销毁,且(1)过程的 ++i 使堆空间中的 i 变为11,从而当函数再次开辟作用域运行时,上溯到fn()作用域找到的 i 已为 11,此时再次使 i 自增得到12,因此结果为20 + 12 = 32;
(3)fn()(10) 为一个匿名函数,此时fn()函数运行产生的作用域没有被显示引用,但是被匿名函数调用,因此在匿名函数执行后被销毁。此时结果为10 + 11 = 21;
(4)由于(3)过程中fn() 的作用域已经销毁,因此(4)过程与(3)无关,此时结果为20 + 11 = 31。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值