js---执行上下文与执行上下文栈

一、变量提升与函数提升

  • 在JavaScript 中,函数声明(function aa(){})与变量声明(var)经常被 JavaScript 引擎隐式地提升到当前作用域的顶部。
  • 函数声明的优先级高于变量,如果变量名跟函数名相同且未赋值,则函数声明会覆盖变量声明
  • 声明语句中的赋值部分并不会被提升,只有变量的名称被提升
1. 变量声明提升

通过var声明的变量,在定义语句之前就可以访问到,值为undefined

2. 函数声明提升

通过function声明的函数,在之前就可以直接调用,值为函数定义(对象)

var a = 3;
function fn() {
	console.log(a); // undefined
	var a = 4;
}
fn();

console.log(b); // undefined
fn2(); // 可调用,函数提升  fn2
fn3(); // 不能,变量提升

var b = 3;
function fn2() {
	console.log('fn2');
}
var fn3 = function() {
	console.log('fn3');
}

二、执行上下文

1. 代码分类

全局代码
函数(局部)代码

2. 全局执行上下文

1、在执行全局代码前将window确定为全局执行上下文
2、对全局数据进行预处理:

  • var定义的全局变量==》undefined,添加为window属性
  • function声明的全局函数==》赋值,添加为window的方法
  • this==》赋值(window)

3、开始执行全局代码

3. 函数执行上下文

1、在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象
2、对局部数据进行预处理

  • 形参变量 => 赋值(实参)=> 添加为执行上下文的属性
  • arguments => 赋值(实参列表),添加为执行上下文的属性
  • var定义的局部变量 => undefined,添加为执行上下文的属性
  • function声明的函数 => 赋值(fun),添加为执行上下文的属性
  • this => 赋值(调用函数的对象)

3、开始执行函数体代码

// 全局执行上下文
console.log(a1, window.a1);
a2();
console.log(this);
 var a1 = 3;
 function a2() {
	console.log('a2()');
}
console.log(a1);

// 函数执行上下文
function fn(a1) {
	console.log(a1);  //2
	console.log(a2);  // undefined
	a3();
	console.log(this);
	console.log(arguments);
	
	var a2 = 3;
	function a3() {
		console.log('a3()');
	}
}
fn(2, 3);

三、执行上下文栈

在全局代码执行前,js引擎会串讲一个栈来存储管理所有的执行上下文对象;
在全局执行上下文(window)确定后,将其添加到栈中;
在函数执行上下文创建后,将其添加到栈中;
在当前函数执行完后,将栈顶的对象移除;
当所有的代码执行完后,栈中只剩下window

var a = 10;
var bar = function(x) {
	var b= 5;
	foo(x + 5);
}
var foo = function(y) {
	var c  = 5;
	console.log(a+c+y);
}
bar(10);
bar(10);

调用函数时才会产生执行上下文,一共有5个执行上下文(包含window)

console.log('gb:' + i);
var i =1;
foo(1);
function foo(i) {
	if (i === 4) {
		return
	}
	console.log('fb:' + i);
	foo(i + 1);
	console.log('fe:' + i);
}
console.log('ge:' + i);

依次输出:
gb: undefined
fb: 1
fb:2
fb: 3
fe: 3
fe: 2
fe: 1
gb: 1
整个过程中产生了5个执行上下文: window,foo1,foo2,foo3,foo4

四、测试题

同一个标识符的情况下,变量声明与函数声明都会提升;函数声明会覆盖变量声明,但不会覆盖变量赋值,即:如果声明变量的同时初始化或赋值那么变量优先级高于函数。

测试题1:
function a() { }
var a;
console.log(typeof a); // function
测试题2:
var c = 1;
function c(c) {
	console.log(c);
}
c(2); // c is not a function

相当于:

var c;
function c(c) {
	console.log(c);
}
c = 1;
c(2); // c is not a function
测试题3:
if (!(b in window)) {
	var b = 1;
}
console.log(b); // undefined
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值