04JS高级-执行上下文与执行上下文栈

22 篇文章 1 订阅

1、变量提升与函数提升

<!--
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()  // undefined

  console.log(b) //undefined  变量提升
  fn2() //可调用  函数提升
  fn3() //不能(会报错)  它属于变量提升
  var b = 3

  function fn2() {
    console.log('fn2()')
  }

  var fn3 = function () {
    console.log('fn3()')
  }
</script>

2、执行上下文

<!--
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) // 3

  console.log("-------------------");

  // 函数执行上下文
  function fn(a1){
    console.log(a1);  // 2
    console.log(a2);  // undefined
    a3();  // a()
    console.log(this); // Window
    console.log(arguments); // Arguments --自己运行看一下,它是一个伪数组[2, 3]

    var a2 = 3;
    function a3(){
      console.log("a3()");
    }
  }
  fn(2,3)
</script>

 3、执行上下文栈

<!--
1. 在全局代码执行前, JS引擎就会创建一个栈来存储管理所有的执行上下文对象
2. 在全局执行上下文(window)确定后, 将其添加到栈中(压栈)
3. 在函数执行上下文创建后, 将其添加到栈中(压栈)
4. 在当前函数执行完后,将栈顶的对象移除(出栈)
5. 当所有的代码执行完后, 栈中只剩下window
-->
<script type="text/javascript">
                              //1. 进入全局执行上下文
  var a = 10
  var bar = function (x) {
    var b = 5
    foo(x + b)               //3. 进入 foo 执行上下文
  }
  var foo = function (y) {
    var c = 5
    console.log(a + c + y)
  }
  bar(10)  //30              //2. 进入bar函数执行上下文
</script>

 

 4、指向上下文栈(面试题)

<!--
1. 依次输出什么?
  gb: undefined
  fb: 1
  fb: 2
  fb: 3
  fe: 3
  fe: 2
  fe: 1
  ge: 1
2. 整个过程中产生了几个执行上下文?  5
-->
<script type="text/javascript">
  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>

5、面试题

<script>

  /*
   测试题1:  函数提升要比变量提升的优先级要高一些,且不会被变量声明覆盖,
             但是会被变量赋值之后覆盖
   */
  function a() {}
  var a;
  console.log(typeof a) // 'function'

  function n() {}
  var n=1;
  console.log(typeof n) // 'number'


  /*
   测试题2:
   */
  if (!(b in window)) {
    var b = 1
  }
  console.log(b) // undefined

  /*
  面试题3 : 输出 undefined
  */
  var a = 3
  function fn () {
    console.log(a)
    var a = 4
  }
  fn()  // undefined

  /*
   测试题4:
   */
  // var c = 1
  // function c(c) {
  //   console.log(c)
  //     var c = 3
  // }
  // c(2) // 报错   c is not a function


console.log("-----------------");

console.log(m);    // f m() {console.log(10)}
console.log(m() + " hahahhah");    //  undefined
var m = 3;

function m() {
		console.log(10) //10
}
console.log(a)   //3
m = 6;
console.log(m());  //m is not a function;

</script>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值