JS上下文环境

参考文章:

深入理解javascript原型和闭包系列——王福明


1.什么是“上下文”

先看demo

	 console.log(a);//undefined
	 console.log(b);//undefined
	 console.log(fun1);//fun1函数体
	 console.log(fun2);//undefined
	 var c="ccc";
	 fun1(c);//ccc
	 fun2(c);//报错:fun2不是个函数

	 var a="aaa";
	 var b;
	 function fun1(x){
	 	console.log(x);
	 	var x=100;
	 }
	 var fun2=function(x){
	 	console.log(x);
	 	var x=100;
	 }
	 

将输出变量a语句写在定义变量a之前,运行没有报错说a变量未定义,而是打印变量a值为undefined。这说明浏览器在执行console.log(a)时,已经知道了a是undefined。所以在执行代码之前有个预编译过程,也就是执行上下文。


2.全局执行上下文环境过程

    2.1执行过程:

        1)把所有var方式定义的变量(包括函数)全部存入上下文,赋值为undefined; 如案例中的fun2

        2)把所有函数声明方式定义的函数名和函数体存入上下文; 如案例中的fun1

        3)this运行时确定(this相当于上下文)

    2.2 函数重名覆盖问题:

        1)声明函数方式覆盖:后面的会覆盖前面的

        2)后面的函数如果是表达式方式定义的,和属性var方式定义是一样的性质,值为undefined不会覆盖声明的函数体


3.全局预编译完毕后,执行代码过程

    3.1所做的事情:

        1)给上下文环境中的变量附上值。

        (非严格模式下,如果变量在上下文环境中不存在,则往上下文环境中加入变量并赋值)

        2)声明方式定义的函数不会再管了,只会处理表达式方式定义的函数

   3.2 执行阶段覆盖问题

         1)后赋值的变量会覆盖先赋值变量内容

        2)执行阶段不会再处理声明方式定义的函数,也就是说声明方式定义函数不会覆盖任何定义的函数和变量,如下方案例

	 var fun="字符串变量	";
	 function fun(){
	 	console.log("声明定义函数")
	 };
	 console.log(fun);//字符串变量
         var fun=function(){
 	 	console.log('变量赋值函数');
 	 };
	 function fun(){
	 	console.log("声明定义函数")
	 };
	 fun()//变量赋值函数

    

4.函数中执行上下文过程

         function fun(a,b){
	 	console.log(a); //1
	 	console.log(b);//函数b的函数体
	 	console.log(arguments);//[1,function b]
	 	var a=20;
	 	function b(){
	 		console.log("funB");
	 	}
	 }
	 fun(1,2);

        4.1 执行时间:调用函数的时候。每调用一次函数,产生一个词法环境(lexical environment)-函数上下文

       4.2 执行过程:

          1)先初始化函数的参数到上下文环境中,保存其参数名和值

          2)内部声明方式定义的函数初始化到上下文环境中

          3)初始化arguments属性,此时argument的参数值会被与参数同名的声明函数覆盖,所以argument的值不一定与传进来的参数值相同,如案例中的console.log(arguments);//[1,function b]

          4)内部var方式定义的变量初始化到词法环境中,赋值为undefined

       4.3 预编译后,执行代码过程

            同全局执行代码过程。

           注意: 非严格模式下,如果函数中变量在上下文环境中不存在(即没有用var定义),则往全局上下文环境中加入变量并赋值。


5.上下文和作用域区别

        作用域只是一个“地盘”,一个抽象的概念,其中没有变量。要通过作用域对应的执行上下文环境来获取变量的值。同一个作用域下,不同的调用会产生不同的执行上下文环境,继而产生不同的变量的值。所以,作用域中变量的值是在执行过程中产生的确定的,而作用域却是在函数创建时就确定了

所以,如果要查找一个作用域下某个变量的值,就需要找到这个作用域对应的执行上下文环境,再在其中寻找变量的值。

    具体参考文章深入理解javascript原型和闭包(13)-【作用域】和【上下文环境】中的案例



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值