Js 执行上下文和作用域
1.执行上下文和执行栈
执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行。
执行上下文的生命周期包括三个阶段:创建阶段→执行阶段→回收阶段,我们重点介绍创建阶段。
创建阶段(当函数被调用,但未执行任何其内部代码之前)会做以下三件事:
创建变量对象:首先初始化函数的参数arguments,提升函数声明和变量声明。
创建作用域链
确定this指向
function test(arg){
// 1. 形参 arg 是 "hi"
// 2. 因为函数声明比变量声明优先级高,所以此时 arg 是 function
console.log(arg);
var arg = 'hello'; // 3.var arg 变量声明被忽略, arg = 'hello'被执行
function arg(){
console.log('hello world')
}
console.log(arg);
}
test('hi');
/* 输出:
function arg() {
console.log('hello world');
}
hello
*/
这是因为当函数执行的时候,首先会形成一个新的私有的作用域,然后依次按照如下的步骤执行:
如果有形参,先给形参赋值
进行私有作用域中的预解释,函数声明优先级比变量声明高,最后后者会被前者所覆盖,但是可以重新赋值
私有作用域中的代码从上到下执行
函数多了,就有多个函数执行上下文,每次调用函数创建一个新的执行上下文,那如何管理创建的那么多执行上下文呢?
JavaScript 引擎创建了执行栈来管理执行上下文。可以把执行栈认为是一个存储函数调用的栈结构,遵循先进后出的原则。
//引用 慕课手记 的图示来示例一下:
console.log(1); function pFn() {
console.log(2);
(function cFn() {
console.log(3);
}());
console.log(4);
}
pFn(); console.log(5);
//输出:1 2 3 4 5

从上面的流程图,我们需要记住几个关键点:
JavaScript执行在单线程上,所有的代码都是排队执行。
一开始浏览器执行全局的代码时,首先创建全局的执行上下文,压入执行栈的顶部。
每当进入一个函数的执行就会创建函数的执行上下文,并且把它压入执行栈的顶部。当前函数执行完成后,当前函数的执行上下文出栈,并等待垃圾回收。
浏览器的JS执行引擎总是访问栈顶的执行上下文。
全局上下文只有唯一的一个,它在浏览器关闭时出栈。
2.作用域与作用域链
ES6 到来JavaScript 有全局作用域、函数作用域和块级作用域(ES6新增)。
我们可以这样理解:作用域就是一个独立的地盘,让变量不会外泄、暴露出去。也就是说作用域最大的用处就是隔离变量,不同作用域下同名变量不会有冲突。
函数作用域:顾名思义就是在这个函数体里边才能访问的变量;当然可以利用闭包来实现跨区域访问局部作用域的变量;查看
块级作用域:ES6新增,用let命令新增了块级作用域,外层作用域无法获取到内层作用域,非常安全明了。即使外层和内层都使用相同变量名,也都互不干扰;
接下来我们再来了解下自由变量(也就是全局变量);
如下代码中,console.log(a) 要得到a变量,但是在当前的作用域中没有定义a(可对比一下b)。当前作用域没有定义的变量,这成为 自由变量。
var a = 100
function fn() {
var b = 200
console.log(a) // 这里的a在这里就是一个自由变量 100
console.log(b) // 200
}
fn()
接下来再看一个示例:
function F1() {
var a = 100
return function () {
console.log(a)
}
}
function F2(f1) {
var a = 200
console.log(f1())
}
var f1 = F1()
F2(f1) //
上述代码中,自由变量a的值,从函数F1中查找而不是F2,这是因为当自由变量从作用域链中去寻找,依据的是函数定义时的作用域链,而不是函数执行时。
那么自由变量的值如何得到 ? —— 向父级作用域 (创建该函数的那个父级作用域)寻找。
如果父级也没呢?再一层一层向上寻找,直到找到全局作用域还是没找到,就宣布放弃。这种一层一层的关系,就是作用域链 。
Js 执行上下文和作用域的更多相关文章
- js - 执行上下文和作用域以及闭包
首先,咱们通常被"执行上下文","执行上下文环境","上下文环境","执行上下文栈"这些名词搞混.那我们一一来揭秘这些名 ...
- js执行环境、作用域
js执行环境.作用域 执行环境:是javascript中的一个重要的概念,<javascript高级程序设计第三版>的定义是:执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行 ...
- JS执行环境,作用域链及非块状作用域
JS中的执行环境,顾名思义就是变量或函数所执行时的环境.在我的理解中,执行环境和作用域相差不大. 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中.而在函数执行之后 ...
- 【repost】 原生JS执行环境与作用域深入理解
首先,我们要知道执行环境和作用域是两个完全不同的概念. 函数的每次调用都有与之紧密相关的作用域和执行环境.从根本上来说,作用域是基于函数的,而执行环境是基于对象的(例如:全局执行环境即window对象 ...
- 浅谈JS执行环境及作用域
今天刚刚开通博客,也是第一次写博文,略感紧张.作为一个表达能力弱弱的人来说,自己花三分钟理解一个知识点,当别人问起时,也许需要30分钟才只是让别人知道自己在说什么,一点也不夸张,希望在博客上可以练习 ...
- JS 执行环境与作用域链
1.执行环境 JavaScript 代码都是在执行环境中被执行的.执行环境是一个概念,一种机制,用来完成JavaScript运行时在作用域.生命周期等方面的处理,它定义了变量或函数是否有权访问其他数据 ...
- js执行上下文和执行栈
执行上下文就是JavaScript 在被解析和运行时环境的抽象概念,JavaScript 运行任何代码都是在执行上下文环境中运行的,执行上下文包括三个周期:创建——运行——销毁,重点说一下创建环节. ...
- js执行上下文栈和变量对象
JavaScript执行上下文栈和变量对象 JS是单线程的语言,执行顺序肯定是顺序执行,但是JS 引擎并不是一行一行地分析和执行程序,而是一段一段地分析执行,会先进行编译阶段然后才是执行阶段. 例子一 ...
- js--执行上下文和作用域相关问题
前言 如果你是或者你想成为一名合格的前端开发工作者,你必须知道JavaScript代码在执行过程,知道执行上下文.作用域.变量提升等相关概念,并且熟练应用到自己的代码中.本文参考了你不知道的JavaS ...
随机推荐
- windows环境下,mysql的root密码丢失后重置方法
运行窗口输入 services.msc,检查mysql服务是否启动,如果启动手动停止或输入 net stop mysql 停止msyql服务. 打开cmd命令行,使用cd命令进入mysql 的bi ...
- sh_14_字符串定义和遍历
sh_14_字符串定义和遍历 str1 = "hello python" str2 = '我的外号是"大西瓜"' print(str2) print(str1[ ...
- codeforces613E
Puzzle Lover CodeForces - 613E Oleg Petrov loves crossword puzzles and every Thursday he buys his fa ...
- 推荐系统系列(三):FNN理论与实践
背景 在FM之后出现了很多基于FM的升级改造工作,由于计算复杂度等原因,FM通常只对特征进行二阶交叉.当面对海量高度稀疏的用户行为反馈数据时,二阶交叉往往是不够的,三阶.四阶甚至更高阶的组合交叉能够进 ...
- (70)一篇文章带你熟悉 TCP/IP 协议
作者:涤生_Woo链接:http://www.jianshu.com/p/9f3e879a4c9c來源:简书著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 同样的,本文篇幅也比较 ...
- Centos7下设置MySql自动启动
原文链接:http://www.cnblogs.com/Sungeek/p/9687565.html 1.将服务文件拷贝到init.d下,并重命名为mysql cp /usr/local/mysql/ ...
- 8.3 CSS样式
8.3 CSS样式 参考链接:http://how2j.cn/k/css2/css2-border/249.html 一.CSS有什么作用. 不使用css 给每一个单元格加上背景颜色 .就需要给每一个 ...
- HTTP中GET与POST的区别颠覆式的理解
关于http中的get和post你轻轻松松的给出了一个“标准答案”: GET在浏览器回退时是无害的,而POST会再次提交请求. GET产生的URL地址可以被Bookmark,而POST不可以. GET ...
- C++入门经典-例7.3-析构函数的调用
1:析构函数的名称标识符就是在类名标识符前面加“~”.例如: ~CPerson(); 2:实例代码: (1)title.h #include <string>//title是一个类,此为构 ...
- 实验四《Android程序设计》实验报告封面
实验四<Android程序设计>实验报告封面 课程:Java程序设计 班级:1753班 姓名:许钰玮 学号:20175329 指导教师:娄嘉鹏 实验日期:2019年5月13日 实验时间:1 ...