278 执行上下文执行上下文栈:变量提升与函数提升,执行上下文,执行上下文栈,全局执行上下文,函数执行上下文,练习题
Posted jianjie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了278 执行上下文执行上下文栈:变量提升与函数提升,执行上下文,执行上下文栈,全局执行上下文,函数执行上下文,练习题相关的知识,希望对你有一定的参考价值。
- 变量提升与函数提升
- 变量提升: 在变量定义语句之前, 就可以访问到这个变量(undefined)
- 函数提升: 在函数定义语句之前, 就执行该函数
- 先有变量提升, 再有函数提升
变量声明提升、函数声明提升
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>01_变量声明提升、函数声明提升</title>
</head>
<body>
<!--
1. 变量声明提升
* 通过var定义(声明)的变量, 在定义语句之前就可以访问到
* 值: undefined
2. 函数声明提升
* 通过function声明的函数, 在之前就可以直接调用
* 值: 函数定义(对象)
3. 问题: 变量提升和函数提升是如何产生的?
-->
<script type="text/javascript">
console.log('-----'); // undefined
var a = 3
function fn() {
console.log(a)
var a = 4
}
fn()
console.log(b); // undefined 变量提升
fn2(); // 可调用 函数提升
// fn3() // 不能调用 变量提升 赋值留在原地
var b = 3
function fn2() {
console.log('fn2()')
}
var fn3 = function() {
console.log('fn3()')
}
</script>
</body>
</html>
- 理解
- 执行上下文: 由 js引擎 自动创建的对象, 包含对应作用域中的所有变量属性
- 执行上下文栈: 用来管理产生的多个执行上下文
- 代码分类(位置):
- 全局: window
- 函数: 对程序员来说是透明的
- 生命周期
- 全局 : 准备执行全局代码前产生, 当页面刷新/关闭页面时死亡
- 函数 : 调用函数时产生, 函数执行完时死亡
- 包含哪些属性:
- 全局 :
- 用var定义的全局变量 ==>undefined
- 使用function声明的函数 ===>function
- this ===>window
- 函数
- 用var定义的局部变量 ==> undefined
- 使用function声明的函数 ===> function
- this ===> 调用函数的对象, 如果没有指定就是window
- 形参变量 ===> 对应实参值
- arguments ===> 实参列表的伪数组
- 全局 :
- 执行上下文创建和初始化的过程
- 全局:
- 在全局代码执行前,最先创建一个全局执行上下文(window)
- 收集一些全局变量, 并初始化
- 将这些变量设置为window的属性
- 函数:
- 在调用函数时, 在执行函数体之前先创建一个函数执行上下文
- 收集一些局部变量, 并初始化
- 将这些变量设置为执行上下文的属性
- 全局:
demo:执行上下文
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>02_执行上下文</title>
</head>
<body>
<!--
1. 代码分类(位置)
* 全局代码
* 函数(局部)代码
2. 全局执行上下文
* 在执行全局代码前将window确定为全局执行上下文
* 对全局数据进行预处理
* var定义的全局变量==>undefined, 添加为window的属性
* function声明的全局函数==>赋值(fun), 添加为window的方法
* this==>赋值(window)
* 开始执行全局代码
3. 函数执行上下文
* 在调用函数, 准备执行函数体之前, 创建对应的函数执行上下文对象(虚拟的, 存在于栈中)
* 对局部数据进行预处理
* 形参变量==>赋值(实参)==>添加为执行上下文的属性
* arguments==>赋值(实参列表), 添加为执行上下文的属性
* var定义的局部变量==>undefined, 添加为执行上下文的属性
* function声明的函数 ==>赋值(fun), 添加为执行上下文的方法
* this==>赋值(调用函数的对象)
* 开始执行函数体代码
-->
<script type="text/javascript">
console.log(a1, window.a1) // undefined undefined
window.a2() // a2()
console.log(this) // window
var a1 = 3
function a2() {
console.log('a2()')
}
console.log(a1) // 2
</script>
</body>
</html>
demo:03_执行上下文栈
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>03_执行上下文栈</title>
</head>
<body>
<!--
1. 在全局代码执行前, JS引擎就会创建一个栈来存储管理所有的执行上下文对象
2. 在全局执行上下文(window)确定后, 将其添加到栈中(压栈) 【window压箱底】
3. 在函数执行上下文创建后, 将其添加到栈中(压栈)
4. 在当前函数执行完后, 将栈顶的对象移除(出栈)
5. 当所有的代码执行完后, 栈中只剩下window
-->
<script type="text/javascript">
var a = 10
var bar = function (x) {
var b = 5
foo(x + b)
}
var foo = function (y) {
var c = 5
console.log(a + c + y)
}
bar(10)
// bar(10)
</script>
</body>
</html>
练习题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>04_执行上下文栈2</title>
</head>
<body>
<!--
1. 依次输出什么?
gb: undefined
fb: 1
fb: 2
fb: 3
fe: 3
fe: 2
fe: 1
ge: 1
2. 整个过程中产生了几个执行上下文? 5
-->
<script type="text/javascript">
// 进栈:
// 出栈:(1)f(4)执行完,f(4)出栈,没有输出; (2)f(4)出栈后,执行f(3)【即foo(i + 1)这行】,执行下面的代码,输出 fe3; (3)同理,f(3)出栈后,执行f(2),输出fe2; (4)f(2)出栈后,执行f(1),输出fe1
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)
</script>
</body>
</html>
demo :05_测试题
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>05_测试题</title>
<link rel="stylesheet" href="xxx.css">
<style>
</style>
</head>
<body>
<script type="text/javascript">
// 测试题1: 先执行变量提升, 再执行函数提升
function a() {}
var a
console.log(typeof a) // 'function'
// 测试题2:
if (!(b in window)) {
var b = 1
}
console.log(b) // undefined
// 测试题3:
var c = 1
function c(c) {
console.log(c)
var c = 3
}
c(2) // 报错
</script>
</body>
</html>
以上是关于278 执行上下文执行上下文栈:变量提升与函数提升,执行上下文,执行上下文栈,全局执行上下文,函数执行上下文,练习题的主要内容,如果未能解决你的问题,请参考以下文章