js中的执行上下文和作用域

一、执行上下文

1、什么是执行上下文?
分析一个问题之前,首先我们都需要知道它是什么。执行上下文又称词法环境,它是存储和处理数据的栈,主要分为两部分:

  • 预处理阶段:
    ①在这个阶段它会将所有的var类型的变量存入上下文中并给它赋值为undefined;
    ②除此之外,它还会将声明的函数存入栈中,并将函数体赋值给它。
    ③还有一个就是this对象

  • 执行阶段:
    ①给词法环境中的变量进行赋值
    ②如果词法环境中不存在这个变量,就把它加入到词法环境并给它赋予相应的值。

2、变量名、函数名冲突问题
如果多个人写js代码,冲突问题是很难避免的,所以我们需要知道什么时候会发生冲突问题,然后改怎么解决。
1)产生冲突问题的情况
①预处理过程:如果两个函数名相同,后面的会覆盖前面的,即使里面的参数个数不同,也会进行覆盖。

            console.log(fun1);
            fun1();
            function fun1(){
                console.log("执行fun1函数");
            }
            function fun1(val){
                console.log("aaa");
            }

这里会输出”aaa”而不是“执行fun1函数”。

②执行阶段:

  • 执行阶段不会再处理声明方式定义的函数;
  • 声明方式定义函数不会覆盖任何定义的函数和属性
  • 后赋值的属性会覆盖先赋值属性内容

③优先级:声明的函数>用var定义的变量;因此,当函数先声明,变量后声明,名字相同但是变量不会将函数进行覆盖,而是将它忽略。

3、案例分析

  • 案例一
            console.log(a);
            console.log(b);
            console.log(fun1);
            console.log(fun2);
            var a=10;
            b=20;
            fun1();
            fun2();
            function fun1(){
                console.log("执行了fun1函数");
            }

            var fun2=function(){
                console.log("执行了fun2函数");
            }

这里写图片描述
一旦代码执行,就会产生一个全局上下文,函数只有被调用的时候才会产生上下文。综上可知,在预处理阶段,全局上下文中会有三个变量,分别为a=undefined fun1(){} fun2=undefined;当执行第一行代码的时候,因为在全局上下文中a还没有被赋值,所以输出undefined;而全局上下文中并没有b,所以这里输出b程序会报错;同理,fun1就是输出它的函数体;fun2=undefined;
当执行到fun1()时,由于fun1在全局上下文中有函数体,所以可以正常输出;而fun2()在全局上下文中仍是undefined,所以这个时候被调用时会报错的。

案例2;

                function fun(a,b){
                console.log(a);
                console.log(b);
                var a=20;
                function b(){
                    console.log("执行了b函数");
                }
            }
            fun(1,2);

这里写图片描述
总共产生了三个上下文,预处理阶段如图所示,由于在fun()中b发生了冲突,由于声明的函数比变量的优先级要高,所以b(){}会将变量b进行覆盖;当执行fun(1,2)这行代码时,a的值会变为1,而执行阶段不会再处理声明方式定义的函数,因此b的输出仍然函数b(){}。

二、作用域

之前学其他语言的时候,也都听说过作用域这个概念,简单来说就是可以使用的范围。与其他语言不通的是,js中的作用域没有块级域之说,不会以{}来进行作用域的分离。

            for(var i=0;i<5;i++){
                var str="aaa";
            }
            console.log(i,str);
            //这里虽然是在for循环里面定义的变量,但是在js中在全局仍可以访问的到

js中的作用域主要分为部分:全局作用域和本地作用域。
作用域和上下文的区别:作用域是在代码写完后作用域就已经确定好了,而上下文会因为代码的执行而发生改变。

  • 整个页面只有一个全局作用域
  • 全局域有一个内置对象,window
  • 所有全局域的变量和方法都绑定到window对象上
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值