部分JS作用域本质【读书有感】

JS作用域的本质:
谈谈JS作用域的本质之前,先谈一下编程语言的功能是什么;
编程语言的功能是什么,用来操作计算机,那么怎样操作计算机呢?无非就是让计算机按照我们的想法,去进行计算,然后得到结果;
那么计算又是计算什么呢?当然是数据呀,那么数据存在哪里呢,当然是内存;
因此,我将编程语言的功能理解为两部分:1.存取数据(将数据存入内存或者从内存中读出) 2.根据内存中的数据指导计算机做运算

现在我们谈一下JS的作用域:
上面说到:编程语言的剧本功能之一就是数据的存取,比如 var a=10,可以理解为在内存中开辟一块空间,命名为a,里面存着数字10。
那么,如果在此基础上写function test(){ var a=100;a=1000; };JS引擎又该怎样处理我函数内部的 var a=10呢;是覆盖?还是重新开辟
空间进行保存?a=1000又怎样处理?
因此,我们需要一套规则来管理变量的存取,于是就引入了作用域的概念

作用域:顾名思义:变量的作用范围。可理解为一个一个的圈子,规则就是:
圈子内可以看见圈子外的数据,圈子外的无权访问圈子内的数据【除非提供相应的出口 例如 闭包】,如果当前圈子内没有找到目标数据,
就会向外层的圈子寻找,直到全局作用域,如果依旧没找到,就报错

     例子:
     function out(){
        var a=10;
        function inner1(){
            console.log(a);
        }
        function inner2(){
            var a=100;
            console.log(a);
        }
        inner1();//输出10
        inner2();//输出100
        console.log(r)//报错
    }
    out();

作用域分类:
词法作用域:写代码时就已经决定了变量的作用范围【我这颗保姆心啊,多想给它解释清楚,哭了】
当然,我们可以通过eval()函数动态插入一些变量来改变词法作用域
比如:function foo(str,a){
eval(str);
console.log(a,b);
}
var b=10;
foo(’var b=100;‘,1);//这里传入的第一个参数就改变了词法作用域
解释:在我们书写的时候,词法分析器会认为 函数foo内部的b是指向外部的【于是很可能会做一些优化】;
但当执行函数时,词法作用域被改变了,指向了临时定义的b=100,这样使得之前的优化毫无意义。
因此,尽量不要使用eval函数

        函数作用域:基于函数的作用域,没什么特别的,就是圈子规则;为了不污染全局作用域,防止命名冲突,隐藏实现细节而设计(个人理解)。
                   值得注意的是,在函数内部访问变量时,如果到全局也没有找到;对于LHS(左查询),则会在全局创建变量;
                   如果是RHS(右查询),则会报错。
                   例如:
                        var x=100;
                        function test(x){
                            a=x;//会在全局创建一个变量a,并将x的值赋给a;
                        }
                        test(x);
                        console.log(window.a)//输出100
                        ----------------------
                        function test2(){
                            var m;
                            m=t;//报错,因为右查询找不到t
                        }
                        test2();
                   注意:对于左查询和右查询,不了解的伙伴百度一下,很简单的
        块级作用域:当我们在使用循环结构,选择结构时,后面的花括号或小括号里变量的作用范围。
                  当我们在使用循环结构,选择结构时,希望后面的花括号里能形成一个单独的作用域,而不污染到当前结构所在的作用域,
                  于是就引入了块级作用域
                  例如:在全局作用域里写 for( var a=0;a<10;a++){
                                            console.log(a)//输出 0-9
                                            var b=100;
                                        }

                                        console.log(a)//输出10
                                        console.log(b)//输出100
                        解释:为什么会输出10,因为 我们是用了 var 来定义了a,而使用var来定义,是没有块级作用域这一说的,
                            于是就相当于 a是在全局中定义的;b也一样;这样的话,无意间就污染了全局作用域;那应该怎么做呢?
                             我们可以将var 换成let 来定义,就出现了块级作用域,let定义的变量就会在自己的块级作用域中,
                             进而解决污染问题。
                             for(let a=0;a<10;a++){
                                    console.log(a);//输出0-9
                                    let  b=100;
                                }
                                console.log(a);//报错
                                console.log(b);//报错
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值