上下文和作用域

变量提升和函数提升

  • 变量提升
var a=3;
function fun(){
    console.log(a)
    var a=5;

    /*
    *var a;
    console.log(a);
    a=5;
    */
}
OUTPUT:undefined
  • 函数提升
fun2()
function fun2(){
    console.log("fun2 is called")
}
fun3()
var fun3=function(){
    console.log("fun3 is called")
}
OUTPUT:fun2 is called  这个是函数提升
OUTPUT:fun3 is not a function  这个是变量提升

全局执行上下文

  • 在执行全局代码前将window确定为全局执行上下文
  • 对全局数据进行预处理
  • var定义的全局变量==>undefined,添加为window的属性
  • function声明的全局函数==>赋值,添加为window的方法
  • this==>赋值(window)
  • 开始执行全局代码

函数执行上下文

  • 在调用函数,准备执行函数之前,创建对应的函数执行上下文对象
  • 对局部数据进行预处理
  • ①形参变量>赋值(实参)>添加为执行上下文的属性
  • ②arguments==>赋值(实参列表),添加为执行上下文的属性
  • function声明的函数==>赋值(fun),添加为执行上下文的方法
  • this==>赋值(调用函数的对象)
  • 开始执行函数体代码
  • 注意,在全局定义的function那一行打不了断点,因为在预处理中定义的,所以不能打断点
function fun(b){
    console.log(b)  ①
    console.log(arguments)②
    console.log(b1)
    console.log(fun1)
    var b1=20;
    function fun1(){

    }
}
fun(20,30)
  • 上下文对象数量(有多少次调用就有多少个上下文对象)
fun 
   fun1
       fun2 
OUTPUT:3+1(window)
---------------------
fun 
     if fun1
     else fun2
OUTPUT:1+1+1(window)  最多三个

  • example
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)
OUTPUT:
gb:undefined
fb:1
fb:2
fb:3
fe:3
fe:2
fe:1
ge:1
注意这里没有对i进行赋值==,所以没有影响i的实际值
  • 变量提升在前
function a(){}
var a;
console.log(typeof a)
OUTPUT:function
  • example
if(!(b in window)){
    var b=1;
}
console.log(b)
OUTPUT: b is undefined,因为{var b=1;},假设这时候还没有块概念,所以b变量提升到全局
  • example
var c = 1;
function c(c) {
    console.log(c)
    var c = 3;
}
c(2)
OUTPUT:c is not a function
解题思路:
c 变量
c 方法
c = 1 =====> 此时c被赋值为1,覆盖掉方法

作用域与作用域链

  • 当一个变量漏定义(没有用var),它将成为全局变量,即使它在函数上下文内
  • 作用域和上下文的区别是作用域是静态的,上下文是动态的,而且一个函数的上下文可以有多次

  • 上下文:n+1

n:函数被调用的次数

  • 作用域:n+1

n:函数的个数

  • example
function fn(){
    var z=100;
}
fn()
console.log(z)
OUTPUT:z is not defined

-example

function fn(){
z=100;
}
fn()
console.log(z)
OUTPUT:100

作用域和上下文区别总结

区别1

  • 全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了,而不是在函数调用时
  • 全局执行上下文环境是在全局作用域确定之后,js代码马上执行之前创建
  • 函数执行上下文环境是在调用函数时,函数体代码执之前创建

区别2

  • 作用域是静态的,只要函数定义好了就一直存在,且不会再变化
  • 上下文环境是动态的,调用函数定义好了就一直存在,且不会再变化
  • 上下文环境是动态的,调用函数时创建,函数调用结束时上下文环境就会被释放

联系

  • 上下文环境是从属于所在的作用域
  • 全局上下文环境==>全局作用域
  • 函数上下文环境==>对应的函数使用
posted @ 2021-02-22 17:38  abcdefgab  阅读(104)  评论(0)    收藏  举报