稳扎稳打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 条评论
登录 后参与评论

相关文章

来自专栏前端知识分享

第38天:运算符、字符串对象常用方法

console.log(0||1);   1 console.log(1||0);   1 console.log(1||5);   1 console.log...

532
来自专栏GreenLeaves

JavaScript之引用类型介绍

       引用类型的值(对象)是应用类型的一个实例。在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,用于将数据和功能组织在一起...

1859
来自专栏coding for love

JS入门难点解析7-this

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

521
来自专栏Deep learning进阶路

C++随记(六)---函数处理数组的一些问题

C++随机(六)---函数处理数组的一些问题 本篇讨论数组做函数形参的情况。 通常,我们按照以往设置形参的习惯,可能会对数组形参做如下的书写: int exa...

1660
来自专栏猿人谷

数组和链表的区别

数组: 数组是将元素在内存中连续存放,由于每个元素占用内存 相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内...

1707
来自专栏函数式编程语言及工具

Scalaz(5)- typeclass:my typeclass scalaz style-demo

  我们在上一篇讨论中介绍了一些基本的由scalaz提供的typeclass。这些基本typeclass主要的作用是通过操作符来保证类型安全,也就是在前期编译时...

1849
来自专栏深度学习之tensorflow实战篇

mongodb11天之屠龙宝刀(九)js函数入门:MongoDB基于js的数据类型修改

mongodb11天之屠龙宝刀(九)js函数入门:MongoDB基于js的数据类型修改 Mongodb并不提供Alter table这样的语句或者工具修...

2894
来自专栏ml

strcpy和memcpy的区别

strcpy和memcpy都是标准C库函数,它们有下面的特点。 strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还...

3146
来自专栏流媒体

Shell编程注意点

682
来自专栏技术点滴

对象的传值与返回

对象的传值与返回 说起函数,就不免要谈谈函数的参数和返回值。一般的,我们习惯把函数看作一个处理的封装(比如黑箱),而参数和返回值一般对应着处理过程的输入和输出。...

1708

扫描关注云+社区