Javascript执行上下文顺序的深入讲解


Posted in Javascript onNovember 04, 2020

一 执行上下文?

1什么是执行上下文?

执行上下文就是当前的 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行的.

2 执行上下文的类型

执行上下文分为三种类型:

全局执行上下文:只有一个,这是默认的,也是基础的执行上下文.(不在任何函数中的代码都是全局执行上下文)他有两个作用,一个是创建了全局变量,也就是指向window下的变量,另一个是将this的指向全局.

函数执行上下文:有无数个,每个函数都拥有自己的执行上下文,但是只有在函数被调用的时候才会被创建,每次调用时,都会为该函数创建一个新的执行上下文…

Eval 函数执行上下文: 指的是运行在 eval 函数中的代码,很少用而且不建议使用。

二 执行上下文的生命周期

1.创建阶段

执行上下文的生命周期有三个阶段:创建阶段?执行阶段—回收阶段(主要说创建阶段)

当函数被调用,但没有执行任何其内部代码之前,会先确定这三个步骤:

1) 创建变量对象:首先初始化函数的参数 arguments,提升函数声明和变量声明
2) 创建作用域链:在执行期上下文的创建阶段,作用域链是在变量对象之后创建的.作用域链本身包含变量对象。
作用域链用于解析变量。当被要求解析变量时,JavaScript 始终从代码嵌套的最内层开始,如果最内层没有
找到变量,就会跳转到上一层父作用域中查找,直到找到该变量。
3) 确定 this 指向:有多种情况.

2. 执行阶段

执行变量赋值、代码执行

3. 回收阶段

执行上下文出栈等待虚拟机回收执行上下文

三. 变量提升和this的指向

1.变量声明提升:

大部分编程语言都是先声明变量再使用,但在 JS 中,事情有些不一样:

console.log(a); // undefined
var a = 10;

上述代码正常输出undefined而不是报错Uncaught ReferenceError: a is not defined,这是因为声明提升.
相当于:

var a; //声明 默认值是undefined “准备工作”
console.log(a);
a = 10; //赋值

2. 函数声明提升

创建函数的方法有两种,一种是通过函数声明function aa(){}

另一种是通过函数表达式var aa = function(){} ,那这两种在函数提升有什么区别呢?

console.log(f1); // function f1(){}
function f1() {} // 函数声明
console.log(f2); // undefined
var f2 = function() {}; // 函数表达式

接下来我们通过一个例子来说明这个问题:

function test() {
 aa(); // Uncaught TypeError "aa is not a function"
 bar(); // "this will run!"
 var aa = function() {
  // function expression assigned to local variable 'aa'
  alert("this won't run!");
 };
 function bar() {
  // function declaration, given the name 'bar'
  alert("this will run!");
 }
}
test();

在上面的例子中,aa()调用的时候报错了,而 bar 能够正常调用。

我们前面说过变量和函数都会上升,遇到函数表达式 var aa = function(){}时,首先会将var aa上升到函数体顶部,然而此时的 aa 的值为 undefined,所以执行aa()报错。

而对于函数bar(), 则是提升了整个函数,所以bar()才能够顺利执行。

细节必须注意:当遇到函数和变量同名且都会被提升的情况,函数声明优先级比较高,因此变量声明会被函数声明所覆盖,但是可以重新赋值。

alert(a); //输出:function a(){ alert('我是函数') }
function a() {
 alert("我是函数");
} //
var a = "我是变量";
alert(a); //输出:'我是变量'

function 声明的优先级比 var 声明高,也就意味着当两个同名变量同时被 function 和 var 声明时,function 声明会覆盖 var 声明
这代码等效于:

function a() {
 alert("我是函数");
}
var a; //hoisting
alert(a); //输出:function a(){ alert('我是函数') }
a = "我是变量"; //赋值
alert(a); //输出:'我是变量'

3. 确定this指向

// 情况1
function foo() {
 console.log(this.a) //1
}
var a = 1
foo() // this->window
// 情况2
function fn(){
 console.log(this);
}
var obj={fn:fn};
obj.fn(); //this->obj

// 情况3
function CreateJsPerson(name,age){
//this是当前类的一个实例p1
this.name=name; //=>p1.name=name
this.age=age; //=>p1.age=age
}
var p1=new CreateJsPerson("尹华芝",48);

// 情况4
function add(c, d){
 return this.a + this.b + c + d;
}
var o = {a:1, b:3};
add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16
add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34

// 情况5
<button id="btn1">箭头函数this</button>
<script type="text/javascript">
 let btn1 = document.getElementById('btn1');
 let obj = {
  name: 'kobe',
  age: 39,
  getName: function () {
   btn1.onclick = () => {
    console.log(this);//obj
   };
  }
 };
 obj.getName();
</script>

结果:

1 this指向window;

2谁调用了函数,谁就是 this,所以在这个场景下 foo 函数中的 this 就是 obj 对象

3 在构造函数中,this 是当前类的一个实例

4call、apply 和 bind:this 是第一个参数

5箭头函数 this 指向:箭头函数没有自己的 this,看其外层的是否有函数,如果有,外层函数的 this 就是内部箭头函数的 this,如果没有,则 this 是 window。

到此这篇关于Javascript执行上下文顺序的文章就介绍到这了,更多相关Javascript执行上下文顺序内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javasciprt下jquery函数$.post执行无响应的解决方法
Mar 13 Javascript
javascript获得当前的信息的一些常用命令
Feb 25 Javascript
node.js中 stream使用教程
Aug 28 Javascript
Vue.js自定义指令的用法与实例解析
Jan 18 Javascript
JavaScript编写一个贪吃蛇游戏
Mar 09 Javascript
源码分析Vue.js的监听实现教程
Apr 23 Javascript
十个免费的web前端开发工具详细整理
Sep 18 Javascript
微信小程序 配置顶部导航条标题颜色的实现方法
Sep 20 Javascript
详解Javascript 中的 class、构造函数、工厂函数
Dec 20 Javascript
基于three.js实现的3D粒子动效实例代码
Apr 09 Javascript
详解key在Vue列表渲染时究竟起到了什么作用
Apr 20 Javascript
通过实例解析javascript Date对象属性及方法
Nov 04 Javascript
解决vant中 tab栏遇到的坑 van-tabs
Nov 04 #Javascript
解决Mint-ui 框架Popup和Datetime Picker组件滚动穿透的问题
Nov 04 #Javascript
基于js实现的图片拖拽排序源码实例
Nov 04 #Javascript
在vant中使用时间选择器和popup弹出层的操作
Nov 04 #Javascript
vue 判断两个时间插件结束时间必选大于开始时间的代码
Nov 04 #Javascript
vant 时间选择器--开始时间和结束时间实例
Nov 04 #Javascript
Vue绑定用户接口实现代码示例
Nov 04 #Javascript
You might like
用PHP制作静态网站的模板框架(二)
2006/10/09 PHP
php操作excel文件 基于phpexcel
2010/07/02 PHP
php使用百度天气接口示例
2014/04/22 PHP
Laravel 5.4向IoC容器中添加自定义类的方法示例
2017/08/15 PHP
PHP自定义函数实现assign()数组分配到模板及extract()变量分配到模板功能示例
2018/05/23 PHP
php如何利用pecl安装mongodb扩展详解
2019/01/09 PHP
文本域中换行符的替换示例
2014/03/04 Javascript
让html页面不缓存js的实现方法
2014/10/31 Javascript
jQuery+HTML5实现手机摇一摇换衣特效
2015/06/05 Javascript
学习JavaScript设计模式(链式调用)
2015/11/26 Javascript
JS实现数组去重复值的方法示例
2017/02/18 Javascript
详解React 16 中的异常处理
2017/07/28 Javascript
详解vue-cli3开发Chrome插件实践
2019/05/29 Javascript
vue+node 实现视频在线播放的实例代码
2020/10/19 Javascript
[06:20]2015国际邀请赛第三日top10
2015/08/08 DOTA
[37:37]DAC2018 4.4 淘汰赛 Optic vs Mineski 第二场
2018/04/05 DOTA
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
Python实现判断一个整数是否为回文数算法示例
2019/03/02 Python
Django import export实现数据库导入导出方式
2020/04/03 Python
Python如何将模块打包并发布
2020/08/30 Python
python输入中文的实例方法
2020/09/14 Python
python+playwright微软自动化工具的使用
2021/02/02 Python
澳大利亚女士时装在线:Rockmans
2018/09/26 全球购物
有趣、实用和鼓舞人心的产品:Inspire Uplift
2019/11/05 全球购物
英国婴儿产品专家:Samuel Johnston
2020/04/20 全球购物
自我鉴定写作要点
2014/01/17 职场文书
药剂专业个人求职信范文
2014/04/29 职场文书
2014年护士长工作总结
2014/11/11 职场文书
房屋租房协议书范本
2014/12/04 职场文书
报名委托书
2015/01/29 职场文书
大学四年个人总结
2015/03/03 职场文书
2015年七年级班主任工作总结
2015/05/21 职场文书
《爬天都峰》教学反思
2016/02/23 职场文书
一篇文章学会Vue中间件管道
2021/06/20 Vue.js
Java8利用Stream对列表进行去除重复的方法详解
2022/04/14 Java/Android
台积电称即便经济低迷也没有降价的计划
2022/04/21 数码科技