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 ...
随机推荐
- 【Winform-自定义控件】ImageButton 支持鼠标正常、悬停、按下更改图片,支持文本
原文地址:https://www.codeproject.com/Articles/29010/WinForm-ImageButton 自定义winfrom图片按钮:支持鼠标正常.悬停.按下更改图片, ...
- JavaStript基础 —— JavaStript语法
JavaStript 简介 JavaScript诞生于 1995年.当然,它的主要目的是处理以前由服务器端语言负责的一些输入验证操作. 如今,JavaStript的用途早就不再局限于简单的数据验证,而 ...
- 4、路由事件 RoutedEvent
路由事件的类型:具体参考https://www.cnblogs.com/jellochen/p/3475754.html Tunnel隧道方式:路由事件使用隧道策略,以便事件实例通过树向下路由(从根到 ...
- luoguP1996 约瑟夫问题
P1996 约瑟夫问题 2.5K通过 4.7K提交 题目提供者 Timothy 标签 洛谷原创 云端 难度 普及- 时空限制 1s / 128MB 题目背景 约瑟夫是一个无聊的人!!! 题目描述 n个 ...
- DB 分库分表(5):一种支持自由规划无须数据迁移和修改路由代码的 Sharding 扩容方案
作为一种数据存储层面上的水平伸缩解决方案,数据库Sharding技术由来已久,很多海量数据系统在其发展演进的历程中都曾经历过分库分表的Sharding改造阶段.简单地说,Sharding就是将原来单一 ...
- javascript中“use strict”的好处和坏处
1.为什么使用严格模式? 消除javascript语法的一些不合理.不严谨之处,减少一些怪异行为: 消除代码运行的不安全之处,保证代码的运行: 提高编译效率,增加运行效率: 为未来新版本的javasc ...
- 快速查找 js 插件
我们是否为一个插件找半天找不到而烦恼 BootCDN 现在不用了,我们可以在 https://www.bootcdn.cn/ 中查找我们想要的任何插件,然后点进去,一直到点进去文件,我们便可以得到 这 ...
- git push 本地项目推送到远程分支[z]
大家有的时候,会在本地新建项目,这里说一下在本地项目建立本地git仓库,然后push到远程仓库的步骤 1.在本地项目的文件夹下,git仓库初始化 git init 初始化本地git仓库 2. git ...
- 阶段3 3.SpringMVC·_07.SSM整合案例_05.ssm整合之Spring整合SpringMVC的框架
点击超连接,执行controller里面的方法 那么就需要在Controller里面定义Service对象,就需要依赖注入进来. 启动tomcat服务器,web.xml里面的前端控制器会帮我加载spr ...
- SpringBoot解决ajax跨域问题(转载)
一.第一种方式: 1.编写一个支持跨域请求的 Configuration import org.springframework.context.annotation.Configuration; im ...