js作用域和作用域链、闭包

全局作用域和局部作用域

全局作用域在任何地方都能被访问:
例如name1 在方法changeName() 里面和外面都可以打印出来

 var name1="haha";
 function changName(){
     var name2="xixi";
     console.log(name1); // haha
     console.log(name2);// xixi
 } 
 changName();
 console.log(name1);//haha
 console.log(name2);//Uncaught ReferenceError: name2 is not defined

在这里插入图片描述
局部作用域一般只在自己的局部区域被访问,在changeName()外面访问 name2 的时候报错,只能在期函数(方法)里面被访问。

作用域链

作用域链决定了全局作用域和局部作用域的变量访问权限。
1、每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链。
2、作用域链是函数被创建的作用域中对象的集合。
3、作用域链可以保证对执行环境有权访问的所有变量和函数的有序访问。
4、沿着作用域一级一级的向上搜索。搜索过程始终是从作用域的前端逐地向后回溯,直到找到(变量、函数)(找不到,就会导致错误发生)。

    var name1 = "haha";

    function changeName() {
        var name2 = "xixi";

        function swapName() {
            console.log(name1); //haha
            console.log(name2); //xixi
            var tempName = name2;
            name2 = name1;
            name1 = tempName;
            console.log(name1); //xixi
            console.log(name2); //haha
            console.log(tempName); //xixi
        }
        swapName();
        console.log(name1); //haha
        console.log(name2); //xixi
        //console.log(tempName);抛出错误:Uncaught ReferenceError: tempName is not defined
    }
    changName();
    console.log(name1);
    //console.log(name2); 抛出错误:Uncaught ReferenceError: name2 is not defined
    //console.log(tempName);抛出错误:Uncaught ReferenceError: tempName is not defined

上述代码中,一共有三个执行环境:全局环境、changeName()的局部环境和 swapName() 的局部环境。所以,

1.函数 swapName()的作用域链包含三个对象:自己的变量对象----->changeName()局部环境的变量对象 ----->全局环境的变量对象。

2.函数changeName()的作用域包含两个对象:自己的变量对象----->全局环境的变量对象。

就上述程序中出现的变量和函数来讲(不考虑隐形变量):

1.swapName() 局部环境的变量对象中存放变量 tempName;

2.changeName() 局部环境的变量对象中存放变量 name2 和 函数swapName();

3.全局环境的变量对象中存放变量 name1 、函数changeName();
 在这里插入图片描述
作用域链相关知识的总结:

1.执行环境决定了变量的生命周期
2.执行环境有全局执行环境(全局环境)和局部执行环境之分。

3.每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链

4.函数的局部环境可以访问函数作用域中的变量和函数,也可以访问其父环境,乃至全局环境中的变量和环境。

5.全局环境只能访问全局环境中定义的变量和函数,不能直接访问局部环境中的任何数据。

闭包

参考链接:https://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

1、闭包就是能够读取其他函数内部变量的函数,因为js语言没有php等后端语言那种类的私有属性概念,所以产生了闭包这种思想。闭包就是将函数内部和函数外部连接起来的一座桥梁。

2、闭包就是让这些变量的值始终保持在内存中(认为是私有属性)。

这就是闭包表现的形式

    var add = (function () {
        var counter = 0;
        return function () {
            return counter += 1;
        }
    })();

    console.log(add());
    console.log(add());

这是作用域指向的案例,在函数表达式getNameFunc中this指的object对象。

  var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());
    var name = "The Window";
    var object = {
        name: "My Object",
        getNameFunc: function () {
            console.log(this);
            var that = this;
            ff = test();
            return ff;
            //这是个孤立的函数,所以他的this指向的是全局window,至于怎么判断是孤立的,凭感觉吧。
            function test() {
                console.log(this);
                return that.name;
            };
        },
    };
    console.log(object.getNameFunc());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值