JavaScript的作用域链 -- 小试牛刀(02)

126 阅读1分钟

书接上文留一下的思考对象中函数this问题,由此引出本篇的主角JavaScript的作用域链。

1、概念

  • 每个函数在创建定义时,就已经规划好了自己专属的一条由内向外的查找变量的路线,称为作用域链。
  • 一个函数把可用的所有作用域串联起来,就行成了当前函数的作用域链。

2、函数作用域链

  • 当执行到某条语句时,Js引擎会自动延函数的作用域链查找要用的变量
<script>
    var a = 10;               // 全局作用域:变量 a
    function fn1(){
        var b = 20;           // fn1作用域:变量 b
        function fn2(){
            var c = 30;       // fn2作用域:变量 c
            console.log(a);
        }
        fn2();
    }
    fn1();
</script>
  • 直接给未定义的变量赋值,相当于直接在全局作用域声明一个变量\color{#0e63e3}{直接给未定义的变量赋值,相当于直接在全局作用域声明一个变量}
<script>
    var a = 10;               // 全局作用域:变量 a
    function fn1(){
        var b = 20;           // fn1作用域:变量 b
        function fn2(){
            var c = 30;       // fn2作用域:变量 c
            i = 100;         // 作用域链上未声明的变量 i,
            console.log(i);
        }
        fn2();
    }
    fn1();
</script>

小结: Js中只有两种局部变量

  • 函数内var定义的
  • 函数的形参变量

3、chrome调试

<script>
    var name = 'The window';
    var object = {
        name: 'my Object',
        getName: function(a) {
            console.log(this.name, arguments);
            return function() {
                return this.name;
            }
        }
    }
    console.log(object.getName(1)());
    // 等效于
    // const returnFun = object.getName(1);
    // const result = returnFun();
    // console.log(result);
</script>

3.1 第一步:创建全局作用域对象(Global);

1644724356(1).jpg

1644724735(1).jpg

3.2 第二步:先调用object.getName(1),函数调用立即生成新的作用域,object调用的getName(),所以this指向object

1644738777(1).jpg 3.3 第三步:返回一个新的fn()

1644738979(1).jpg 3.4 第四步:执行object.getName(1)()最后的()(即 第三步 返回的fn());

1644739238(1).jpg

1644739600(1).jpg

4、上章思考题

<script>
    var lilei={ 
        name: "冰墩墩",
        intr: function(){
            console.log(`我是奥运吉祥物${this.name}`) 
        }
    } 
</script>
  1. intr: function(){}函数内形成自己的作用域,父作用域为window,如果去掉thisname在函数作用域内和父级作用域内都查找不到,所以不能去掉this。
  2. function()不能换成 => 函数, 因为 =>创建之初会始终指向外部对象,那么this将指向undefined

this指向问题下章详谈,欢迎继续关注。