稳扎稳打JS——执行上下文

上下文环境的初始化在代码执行前完成

  • JS有三种作用域:全局作用域、函数作用域、eval作用域(不常用,不做介绍)。
  • 在JS代码执行前,首先会对这三种作用域进行上下文环境的准备工作,准备内容如下:
    1. 全局作用域的上下文准备工作
      • 将全局变量设为undefined
      • 将函数表达式的值设为undefined
      • 为函数声明直接赋值
      • 将window对象赋给this
    2. 函数作用域的上下文准备工作
      • 确定自由变量的作用域
      • 为函数的参数和arguments对象赋值
      • 将局部变量的值设为undifined
      • 将函数表达式的值设为undifined
      • 为函数声明直接赋值
//将全局变量的值设为undefined
console.log(a); //undefined
var a = 1;

//将window对象赋给this
console.log(this);

//将函数表达式的值设为undefined
console.log(fn1);//undefined
var fn1 = function(){
    //……
}

//为函数声明直接赋值
console.log(fn2); //输出函数的代码
function fn2(){
    //……
}

//函数作用域
function fn3(b,c){
    //确定自由变量的作用域
    console.log(a);

    //为局部变量赋上undefined
    console.log(x);//undefined
    var x = 123;

    //为函数的参数赋值
    console.log(b,c); //2,3

    //为arguments赋值
    console.log(arguments); //[2,3]
}

fn3(2,3);
  • 函数作用域中this的是在JS运行时才能确定,而全局作用域中的this在准备上下文环境的时候就确定了(window)。
  • 定义函数有两种方法:函数声明式定义、函数表达式定义,如下所示:
//函数声明式定义
function fn(a,b){
    //……
}

//函数表达式定义
var fn = function(a,b){
    //……
}
  • 两者区别如下:
    • 若采用函数声明式定义,函数调用语句和函数声明语句的先后次序无关。 因为在代码运行前的准备上下文环境过程中,函数的初始化已经完成,所以运行时无论函数调用语句在哪儿,JS编译器都能调用这个函数。
    • 若采用函数表达式来定义函数,则函数定义一定要在函数调用语句之前! 因为在这种方式中,函数的初始化是在运行时完成,在代码运行前只是将undefined赋给函数变量。因此在这种情况下,函数调用语句必须在函数定义后。
  • JS中作用域只有三种:全局作用域、函数作用域、eval作用域。除此之外就没有作用域了!如:for、if、while等都不是独立的作用域! 因此在里面定义的局部变量都属于其所属的外层作用域。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java 源码分析

Java面向对象基础(二)

1.构造器: 构造函数在一个类没有写任何的构造函数的时候,系统会生成一个默认的空参数构造函数,这个构造函数的修饰符就是类的修饰符,当我们定义了一个构造函数,默认...

3397
来自专栏Crossin的编程教室

【Python 第71课】变量的作用域

在写代码的时候,免不了要使用变量。但程序中的一个变量并不一定是在哪里都可以被使用,根据情况不同,会有不同的“有效范围”。看这样一段代码: def func(x)...

32211
来自专栏java一日一条

常见Java面试题 – 第三部分:重载(overloading)与重写(overriding)

这篇文章介绍的常见面试题是关于重载(overloading)方法和重写(overriding)方法的。Q.下面代码片段的输出结果是什么?

652
来自专栏向治洪

传统多线程之前如何共享数据

几种方式 线程执行代码相同,使用同一Runnable对象,Runnable对象中有共享数据 线程执行代码不同,将共享数据封装在另一对象中(操作数据的方法也在该...

18610
来自专栏青青天空树

c++中string的常用函数说明

string可以说是是字符数组的升级版,使用更加啊方便,不容易出错。本文对string的常用函数进行简单介绍,做到会用即可。

591
来自专栏mySoul

C++命名空间

1072
来自专栏领域驱动设计DDD实战进阶

07-TypeScript的For循环

在传统的JavaScript中,关于循环,可以有两种方式,一种是forEach,一种是for。 forEach的用法如下: var sarr=[1,2,3,4]...

3034
来自专栏java一日一条

Java的内存机制

Java 把内存划分成两种:一种是栈内存,另一种是堆内存。在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,当在一段代码块定义一个变量时...

630
来自专栏鬼谷君

python3 内置函数详解

1353
来自专栏ShaoYL

预处理指令(条件编译)

35911

扫码关注云+社区