javascript 函数作用域 (VS Javascript 块级作用域)

1、JavaScript 函数作用域

函数作用域定义的是函数定义的时候所处最近的上级函数上下文,而非调用的时候所处的函数环境。
函数作用域与函数定义相关,与函数调用无关。
例1:demo-1.js
function f1 () {
    var num = 1;

    function f2 () {
        var num = 2;
        f3();
    }
    f2();

    function f3 () {
        console.log(num);
    }
}
f1();
//输出:1

通过下图的“作用域关系表”可以看出,f3函数中没有定义num变量,所以只能向上(即外层环境)寻找名为num的变量。

函数f2和函数f3处于平级,所以f3只能获得函数f1对应的变量对象中的num值,即使f3在f2中调用。

作用域关系表:



相关术语:

函数作用域”指:由执行环境对应的变量对象形成的作用域链。
 
 
什么是“执行环境”:每个函数都有自己的执行环境。
什么是“变量对象”:函数定义时内部的声明定义的变量、声明定义的函数、以及函数的参数。


2、JavaScript 函数作用域 比较 JS 块级作用域
for循环示例

2-1  

js 函数作用域:
var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

解析:数组a中的每个数组项的值都是一个函数,函数为
function () { console.log(i); };,因为函数并没有执行,所以函数体中的 i 不会被替换成变量。
如果数组项运行后,则将 i 的值打印出来,此时 i 的值又是什么呢?
现在来创建一下作用域关系表:

如图所示,运行数组项值(即匿名函数)时,访问的 i 是全局变量对象中的 i。

但是 i 的值为什么是10呢? 
js有两种数据类型,分别是基本数据类型(undefined,null,Number,String,Boolean),
和引用数据类型(包含一项至多项数据名值对)。
区别之一是基本数据类型可以直接改写数据值,而引用数据类型包含的值是数据的引用(即数据在堆内存中的地址),不能直接改写数据值。
此时,由于没有创建新的变量 i,所以i的值每循环一次被改写一次,最终值为10。

相关术语:
js变量提升:变量的声明(不是定义)会自动提升到包含该变量的最近的函数顶部。

PS: 如果把匿名函数运行后的值传给数组,则a[6]的值为6。
如下:
var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = (function () {
    console.log(i);
  })();
}
console.log(a[6]); // 6

2-2

js 块级作用域:
var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6
相当于:
var a = [];
for (let i = 0; i < 10; i++) {
    (function () {
        a[i] = function () {  
<span style="font-family: Arial, Helvetica, sans-serif;">                    console.log(i);</span>
<span style="font-family: Arial, Helvetica, sans-serif;">              };</span>
    })();
}
a[6](); // 6

解析:同理函数作用域示例,不同处在于i的作用域仅在for循环语句块中。
每次循环都相当于再次创建一个变量,虽然变量 i 同名,但所指的值不同。
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值