js -- 作用域和闭包的笔记

笔记的知识大部分来自 https://www.cnblogs.com/wangfupeng1988/p/3992795.html和<JavaScript权威指南>

1. 作用域

   自由变量:在A作用域中使用的变量x,却没有在A作用域中声明(即在其他作用域中声明的),对于A作用域来说,x就是一个自由变量

    看到这样一段代码,对fn来说,x就是自由变量

var x = 10;
function fn() {
    console.log(x);
}
function show(f) {
    var x = 20;
    f();
}
show(fn); //10

    这个代码执行出来是10。

    原因: 要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”,其实这就是所谓的“静态作用域”。去创建fn函数的那个作用域中取——无论fn函数将在哪里调用。

上面描述的只是跨一步作用域去寻找。

如果跨了一步,还没找到呢?——接着跨——一直跨到全局作用域为止。要是在全局作用域中都没有找到,那就是真的没有了。

这个一步一步“跨”的路线,我们称之为——作用域链。

    取自由变量时的这个“作用域链”过程:(假设a是自由量)

第一步,现在当前作用域查找a,如果有则获取并结束。如果没有则继续;

第二步,如果当前作用域是全局作用域,则证明a未定义,结束;否则继续;

第三步,(不是全局作用域,那就是函数作用域)将创建该函数的作用域作为当前作用域;

第四步,跳转到第一步。

我之前一直是简单记为从内向外找变量直到找到window下。

在网上还找了一个例子,结合上面的说明,倒是有点理解输出结果了:

function f1(){
    var n=999;
    nAdd=function(){n+=1}
    function f2(){
        console.log(n);
    }
    return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000

2. 闭包

两种情况:函数作为返回值, 函数作为参数

2.1 函数作为返回值

function fn() {
    var max = 10;
    return function bar(x) {
        if(x > max){
            console.log(x);
        }
    }
}
var f1 = fn();
f1(15); //15

怎么取的max,就如同前面作用域讲得那样:去创建fn函数的那个作用域中取——无论fn函数将在哪里调用。

2. 2 函数作为参数

var max = 10;
fn = function (x) {
    if(x > max){
         console.log(x); //15
        console.log(max); //10
    }
}
;(function(f) {
  var max = 100;
  f(15);
})(fn);

同样的道理,fn里面取max就是在fn定义的作用域里面取max,即第一行 var max = 10;

在<JavaScript权威指南>里面,8.6闭包这一章有几句原话:

“函数的执行依赖于变量作用域,这个作用域是函数定义时决定的,而不是函数调用时决定的。”

“函数体内的变量都可以保存在函数作用域内,这种特性在计算机科学文献中称为‘闭包’。”

“函数定义时的作用域链到函数执行时仍然有效。”

以上三句箴言默念几遍以后,不管内在原理懂没有,至少函数变量取值会看了吧。

作用域和闭包暂且到此吧,因为我水平不够,再多复制粘贴大神的自己也无收获,此处写下的算是我能hold住的,其余等技术上升后再补充吧。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值