三、函数高级(五)- 变量查找

一、前提

	
	1、原型与原型链
			原型链的作用就是查找对象的属性。
			
	2、执行上下文与执行上下文栈
			执行上下文的作用就是保存当前作用域环境的初始化变量。
			
				创建:JS执行全局代码前或函数代码前,会设置执行上下文对象,并初始化环境。
				死亡:函数执行完毕就会销毁。
			
	3、作用域与作用域链
			作用域链的作用就是查找变量。
			作用域链的代码实现就是函数内部属性[[scopes]]属性。
				
	4、闭包
			闭包的作用就是延长函数变量的生命周期。
			闭包本质上就是闭包作用域对象。
			


二、变量查找机制


	+++ 基础
	  		1) 沿着作用域链查找变量:
	  				确定当前函数的作用域链,
	  				首先在当前作用域中对应的执行上下文对象中查找变量,
	  				如果找不到,就会到上一级作用域中对应的执行上下文对象中查找。直到全局作用域。
	  	
	  		2) 沿着原型链查找对象属性
		
	+++ 变量查找机制
				1) 首先在自身作用域中对应的执行上下文对象中查找。
				2) 如果找不到,就会到函数的作用域链属性中查找。
						从索引值0开始依次向上查找。
			
						
				3)查找到变量后,如果继续查找对象的属性,则会沿着原型链查找。
		
	
	注意事项:
			1) 作用域是在函数定义时确立的。而不是在函数调用时确立的。
			2) 作用域只分为全局作用域和函数作用域
			
			3) 在全局作用域中定义的变量会被当做window的属性来保存。
	   		   不使用var关键字定义的变量会被当作window的属性来保存。
			
			4) 作用域链与原型链都是用于查找对象的属性。
						在作用域链查找变量是沿着作用域链查找。
						在对象中查找属性是沿着原型链查找。
					

3.1 变量查询机制
1)案例1

首先在自身作用域中对应的执行上下文对象中查找fn,
.
找不到就会到作用域链属性中查找,此时,作用域链属性中只有window对象,则会到window对象中查找fn。


	var fn=function(){
		
		//首先在自身作用域中查找变量fn。
		//然后到全局作用域查找变量fn。
	    console.log(fn)
	}
	
	fn();
	

2)案例2

首先在自身作用域中对应的执行上下文对象中查找this.


	var obj={
	    fn2:function(){
	    	//查找obj对象中的fn2
	        console.log(this.fn2);
	    }
	}
	
	obj.fn2();  

>>>>>> 作用域只分为全局作用域和函数作用域

作用域只分为全局作用域和函数作用域。

虽然fn2是obj的属性,但是作用域只分为全局作用域和函数作用域。所以fn2函数的所在的作用域链fn2函数作用域 > 全局作用域。
查找变量:首先在fn2作用域中查找fn2变量,找不到,然后到全局作用域查找,找不到后报错。


	var obj={
	    fn2:function(){
	    	
	    	//首先在自身作用域中查找变量fn2.
	    	//然后到全局作用域中查找变量fn2,找不到,报错。
	        console.log(fn2);
	    }
	}
	
	obj.fn2();  //报错	

>>>>>> 作用域是在编码时就已经确立的,不会改变
	
	虽然fn函数在show函数中调用,但是fn函数的作用域链是在定义时就已经确定了,而不是调用时确定。
	
	fn函数作用域链:fn函数作用域 > 全局作用域。
	

    var x=10;

    function fn(){
        console.log(x)
    }

    function show(f){
        var x=20;
        f();
    }

    show(fn);
3)案例3

首先在getNameFun函数对应的执行上下文中查找this,此时this指向window。
然后会到window中查找name

        //案例一
        var name='The Window'
        var obj={
            name:'My Object',
            getNameFun:function(){
                return function(){
                    return this.name;
                }
            }
        } 

        console.log(obj.getNameFun()())

首先在匿名函数对应的执行上下文中查找that
找不到就会到函数中的作用域链属性中查找。此时作用域链属性从0开始依次是闭包作用域对象、window对象。
从索引值0开始查找,找到that。
然后沿着that的原型链查找name。

  //案例er
        var name='The Window'
        var obj={
            name:'My Object',
            getNameFun:function(){
                var that=this;
                return function(){
                    return that.name;
                }
            }
        } 

        console.log(obj.getNameFun()())
3.3 作用域链、执行上下文与变量查询的内在联系
	
	执行上下文与作用域的关系:
			1、作用域的作用是隔离变量。
			2、作用域链的作用是查询变量。
			
			3、作用域、作用域链是在编码时就已经确定了,而执行上下文对象是在代码执行前或函数执行时确立的。
			   执行上下文对象从属于作用域。
				
	函数在查找变量时,
			1、首先会在当前作用域中对应的执行上下文对象查找变量,
			   这是由于在执行代码前,会初始化代码数据,此时会将变量或函数放入到执行上下文对象中。
			
			2、如果找不到,就到上一级作用域对应的执行上下文对象中查找。
	
	

三、JS执行过程解析

3.1 执行上下文与作用域的直观展示
	var s=12;
    function ff(){
        //此时闭包已经产生了。(函数提升,内部函数对象已经创建了)
        var a=1;

        function f(){
            a++;
            console.log(a)
        }

        return f;
    }

    var f=ff();
    f(); //2
    f();//3

在这里插入图片描述

4.2 JS代码执行全流程讲解

	
	+++ 前提:
			1JS执行代码前首先会创建一个执行上下栈。
			2、在创建执行上下文对象后会将执行上下对象放入到栈中。函数执行完毕,会将该对象从栈中移除。
			3、执行上下文栈中最终存储window执行上下文。
		
	+++ JS全流程讲解		
			1JS代码执行时,首先会将Window设置为全局执行上下文。
			2、然后初始化全局数据:
							  变量声明提前,并设置为window属性。
							  函数声明提前(函数声明实质上就是创建函数对象),并设置为window属性。
							  将this设置为window对象。
							  
			3、执行全局代码。				  
			
			4、执行到某个函数时
						1、创建函数执行上下文。
						2、初始化函数数据
							  变量声明提前,并设置为window属性。
							  函数声明提前(函数声明实质上就是创建函数对象),并设置为window属性。
							  
							  函数形参赋值,并设置为函数执行上下文的属性。
							  函数arguments赋值,并设置为函数执行上下文的属性。
							  函数中this设置为window对象。
							  
						3、执行函数代码	  
				
	+++ JS查找变量
			   函数沿着作用域链查找变量时, 首先在当前作用域中对应的执行上下文对象中查找变量,
	  		   如果找不到,就会到上一级作用域中对应的执行上下文对象中查找。直到全局作用域。
			
	
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值