剖析JS 的 作用域和预编译过程

1.js执行三部曲

1.语法分析

程序在最开始时的时候回通篇的扫描一遍,看是否有低级的语法错误。

2.预编译

函数声明整体提升,变量 声明提升

1) 预编译前奏
  1. imply global 暗示全局变量 : 即任何变量,如果变量未经声明就赋值,此变量就位全局对象所有。

    a = 123;
    
  2. 一切声明的全局变量,全是window 的属性

    var a = 123;  ===  window.a = 123;
    
function fn(a) {
	console.log(a);
	var a = 123;
	console.log(a);
	function a() {}
	console.log(a);
	var b = function() {}
	console.log(b);
	function d() {}
}
fn(1);
2) 预编译的四部曲

通过上面代码来解释预编译的步骤

AO : 执行期上下文,存储空间库

一、局部 生成的是AO

  1. 创建AO (执行期上下文 )对象

    AO{
       
    }
    
  2. 找形参和变量声明,将变量和参数作为AO 属性名,值为undefined

    AO{
        a : undefined,
        b : undefined
    }
    
  3. 将实参值和形参值统一

    AO{
       a : 1,
       b : undefined
    }
    
  4. 在函数体里面找函数声明,值赋予函数体

    AO{
       a : function a() {}
       b : undefined,
       d : function d() {}
    }
    

二、全局 生成的是 GO === window

  1. 创建GO 对象
  2. 找形参和变量声明,将变量和参数作为GO 属性名,值为undefined
  3. 在函数体里面找函数声明,值赋予函数体

注意: 先有GO 在有 AO

练习:

练习1 
global = 100;
function fn() {
	console.log(global);
	global = 200;
	console.log(global);
	var golbal = 300;
}
fn();
var global;

运行结果: undefind 200


练习2
function test() {
	console.log(b);   // undefind 
	if(a) {
		var b = 100;
	}
	c = 234;
	console.log(c);  //234
}
var a ;
a = 10;
console.log(c);  //234

练习题3
function bar() {
	return foo;
	foo = 10;
	function foo() {}
	var foo = 11;
}
console.log(bar())   // function foo() {}

练习4 
function bar() {
	foo = 10;
	function foo() {}
	var foo = 11;
	return foo;
}
结果 : 11

练习5 
 a = 100;
 function demo(e) {
 	function e() { }
 		arguments[0] = 2;
         console.log(e);  // 2
         if(a) {
         	var b = 123;
         	function c() {}  //在if 中是不能放function 的
         }
 	
 	var c ;
 	a = 10;
 	var a;
 	console.log(b);  // undefined
 	f = 123;
 	console.log(c);  //undefined
 	console.log(a);  //10
 }
 var a;
 demo(1);
 console.log(a);  //100
 console.log(f); // 123
  
 

3. 解释执行

2.作用域

[[scope]] : 每一个javascript 函数都是一个对象,对象中有些属性我们可以访问,但是有些不可以,这些属性仅提供javascript引擎存取,[[scope]] 就是其中一个。

[[scope]] : 指的就是我们所说的作用域,就是存储运行期的执期上下文集合。

作用域链 : [[scope]] 中存储的执行器上下文对象的集合,这个集合呈现链式链接,我们把这种链式链接叫做作用域链。

1、运行期上下文:

  • 当函数执行时,会创建一个称为 执行期上下文的内部对象。

  • 一个执行期上下文定 义了一个函数执行时的环境,函数每次执行时对 应的执行上下文都是独一无二的,所以多次调用 一个函数会导致创建多个执行上下文,

  • 当函数执 行完毕,它所产生的执行上下 被销毁

2、查找变量:从作用域链的顶端依次向下查找(在谁的函数上找,则在谁的作用域链从顶端开始上找)。

实例:

下列程序的执行过程:
在这里插入图片描述

1.被定义时
在这里插入图片描述

  1. a函数执行

在这里插入图片描述

  1. b定义的时候(保存的是a 的引用)
    在这里插入图片描述

  2. b执行

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值