js - 执行上下文和作用域以及闭包
首先,咱们通常被"执行上下文","执行上下文环境","上下文环境","执行上下文栈"这些名词搞混。那我们一一来揭秘这些名字的含义。
这一块一直比较晦涩难懂,还是需要仔细去斟酌斟酌。
什么是执行上下文(也叫做“执行上下文环境”,“上下文环境”)?
咱们还是先看代码。
console.log(a) // undefined
var a = 100 fn('bella') // 'bella' 20
function fn(name) {
age = 20
console.log(name, age)
var age
} console.log(b); // 这里报错
// Uncaught ReferenceError: b is not defined
第一个console输出 undefined,说明浏览器在执行console.log(a)的时候,已经知道a的存在的,但是不知道a的值。
第二个fn("bella")输出 "bella" 20,说明浏览器在执行的时候已经知道fn函数了,并且执行了
第三个console报错,b is noe defined。说明没有找到b
那么可以看出来,浏览器在执行之前做了一些准备工作。
那做了些什么准备工作:
- 全局上下文环境: 变量定义,函数声明
- 函数上下文环境(函数内部):变量定义,函数声明,this,arguments
下面这个例子很多地方都用来讲解执行上下文和上下文栈。
// 这是一个压栈出栈的过程--执行上下文栈
let a = 10; // 1、进入全局上下文环境
let fn;
let bar = function(x) {
let b = 5
fn(x + b) // 3、进入fn函数上下文环境
};
fn = function(y) {
let c = 5
console.log(y + c)
} bar(10) // 2、 进入bar函数上下文
这里引出了执行上下文栈的概念,上下文栈就是压栈和出栈的过程。
1.在代码执行之前,首先创建全局上下文环境
// 全局上下文环境
a: undefined
fn: undefined
bar: undefined,
this: window
2.然后执行代码,在代码执行到12之前,全局上下文中的变量在执行中被赋值
// 全局上下文环境
a: 10
fn: function
bar: function,
this: window
然后执行13行代码,调用bar函数,会创建一个新的执行上下文环境。并将这个bar上下文环境压栈,并设置为活动状态
// bar函数上下文环境
b: undefined
x: 10
arguments: [10]
this: window
3.然后执行到第6行代码,调用fn的时候,会创建一个新的执行上下文。并将这个fn上下文环境压栈,并设置为活动状态。
// fn函数上下文环境
c: undefined
y: 15
arguments: [15]
this: window
4.fn执行完毕后,调用fn函数生成的fn上下文环境出栈,销毁。然后bar出栈销毁。然后全局上下文出栈销毁
理解完了执行上下文,再看看this
相信都知道这句话,谁调用函数,this就指向谁。那么我们理解下this:
var a = {
name: 'A',
fn: function() {
console.log(this.name)
}
}
a.fn() // this === a
a.fn.call({
name: 'B'
}) // this === {name: 'B'}
var fn1 = a.fn
fn1() // this === window
this: this的值只有在执行的时候才能确认,定义的时候不能确认。因为this是执行上下文的一部分,而执行上下文需要再代码执行之前确定。
- 作为构造函数执行,构造函数中
- 作为对象属性执行,上述代码中a.fn()
- 作为普通函数执行,上述代码中fn1()
- 用于call apply bind,上述代码中a.fn.call()
作用域
作用域链
let a = 100
function fn() {
let b = 20
function bar() {
console.log(a + b) // a是自由变量
}
return bar
} let x = fn(), b = 200
x()
function F1() {
var a = 100
return function () {
console.log(a)
}
}
var f1 = F1()
var a = 200
f1()
- 函数作为返回值,上面的例子就是
- 函数作为参数传递
js - 执行上下文和作用域以及闭包的更多相关文章
- Js 执行上下文和作用域
1.执行上下文和执行栈 执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行. 执行上下文的生命周期包括三个阶 ...
- js执行环境、作用域
js执行环境.作用域 执行环境:是javascript中的一个重要的概念,<javascript高级程序设计第三版>的定义是:执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行 ...
- JS三座大山再学习 ---- 作用域和闭包
本文已发布在西瓜君的个人博客,原文传送门 作用域 JS中有两种作用域:全局作用域|局部作用域 栗子1 console.log(name); //undefined var name = '波妞'; v ...
- 我不知道的js(一)作用域与闭包
作用域与闭包 作用域 什么是作用域 作用域就是一套规则,它负责解决(1)将变量存在哪儿?(2)如何找到变量?的问题 作用域工作的前提 谁赋予了作用域的权利?--js引擎 传统编译语言编译的过程 分词/ ...
- JS执行环境,作用域链及非块状作用域
JS中的执行环境,顾名思义就是变量或函数所执行时的环境.在我的理解中,执行环境和作用域相差不大. 每个函数都有自己的执行环境,当执行流进入一个函数时,函数的环境就会被推入一个环境栈中.而在函数执行之后 ...
- 【repost】 原生JS执行环境与作用域深入理解
首先,我们要知道执行环境和作用域是两个完全不同的概念. 函数的每次调用都有与之紧密相关的作用域和执行环境.从根本上来说,作用域是基于函数的,而执行环境是基于对象的(例如:全局执行环境即window对象 ...
- 浅谈JS执行环境及作用域
今天刚刚开通博客,也是第一次写博文,略感紧张.作为一个表达能力弱弱的人来说,自己花三分钟理解一个知识点,当别人问起时,也许需要30分钟才只是让别人知道自己在说什么,一点也不夸张,希望在博客上可以练习 ...
- JS 执行环境与作用域链
1.执行环境 JavaScript 代码都是在执行环境中被执行的.执行环境是一个概念,一种机制,用来完成JavaScript运行时在作用域.生命周期等方面的处理,它定义了变量或函数是否有权访问其他数据 ...
- js原型链,作用域,闭包讲解
当面试的时候遇到问原型链,闭包,还有作用域,直接 拿张纸和笔把原型链画出来,闭包跟作用域直接用笔写几道题出来加深理解(因为我们是理科生,图形和题目以及控制台输出结果才是最直观的方法) 问:什么是原型链 ...
随机推荐
- 怎样提高js的编程能力
1,学习js分几个阶段,没入门,入门初学者,中级水平,高级水平,ppt水平. 2,没入门的如何学习? 我当初是先学jquery,有css和html基础,有css基础看jq的语法很简单,就是选择符,jq ...
- Day05:集合操作——线性表(二) / 查找表 / 文件操作——File(一)
文件操作:https://www.cnblogs.com/wsnb8/p/11403626.html
- Mybatis操作数据时出现:java.sql.SQLSyntaxErrorException: Unknown column 'XXX' in 'field list'
这个错误比较重要,而且很常见,故单独进行说明: Mybatis出现:Unknown column 'xxx' in 'field list' 先来看一下程序的内部: dao.addUser(" ...
- 【HANA系列】SAP HANA SQL从给定日期中获取年份
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL从给定日 ...
- linux分区知识
1.硬盘使用前,一般要分区,格式化(创建文件系统)--存放数据(极端情况下,可以不分区) 2.分区: 主分区. 扩展分区.逻辑分区 主分区+拓展分区的数量<=4,其中一个主分区可以用一个拓展分区 ...
- Redhat7 安装 yum(换成免费版) 安装gcc
最近上Linux系统基础课程,要在虚拟机上编译运行程序,这时候就需要安装gcc,网上一搜,各种什么在线,离线安装,其中在线安装很方面,一个命令 yum install gcc 即可解决 可我这么输入后 ...
- PTA(Basic Level)1026.程序运行时间
要获得一个 C 语言程序的运行时间,常用的方法是调用头文件 time.h,其中提供了 clock() 函数,可以捕捉从程序开始运行到 clock() 被调用时所耗费的时间.这个时间单位是 clock ...
- SQLite基础-2.PyCharm+Database_Navigator
目录 一.PyCharm + Database Navigator插件 二.SQLite Expert – Personal Edition 三.SQLite Administrator 一.PyCh ...
- 如何用纯 CSS 创作一个慧星拖尾效果的 loader 动画
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/YLRLaM 可交互视频教 ...
- hashmap存储数据
在HashMap中,为什么不能使用基本数据类型作为key? 其实和HashMap底层的存储原理有关,HashMap存储数据的特点是:无序.无索引.不能存储重复元素. 存储元素采用的是hash表存储数据 ...