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 相关文章推荐
25个非常棒的jQuery滑块插件和教程小结
Sep 02 Javascript
原生JS实现表单checkbook获取已选择的值
Jul 21 Javascript
javascript判断两个IP地址是否在同一个网段的实现思路
Dec 13 Javascript
js清空form表单中的内容示例
May 20 Javascript
谷歌浏览器调试JavaScript小技巧
Dec 29 Javascript
js实现功能比较全面的全选和多选
Mar 02 Javascript
详解Angular 4 表单快速入门
Jun 05 Javascript
vue增删改查的简单操作
Jul 15 Javascript
纯js实现隔行变色效果
Nov 29 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
Apr 09 Javascript
Vue 页面跳转不用router-link的实现代码
Apr 12 Javascript
对TypeScript库进行单元测试的方法
Jul 18 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
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
php数组函数序列 之array_count_values() 统计数组中所有值出现的次数函数
2011/10/29 PHP
php中3des加密代码(完全与.net中的兼容)
2012/08/02 PHP
分享PHP header函数使用教程
2013/09/05 PHP
php生成百度sitemap站点地图类函数实例
2014/10/17 PHP
PHP使用CURL模拟登录的方法
2015/07/08 PHP
PHP实现多文件上传的方法
2015/07/08 PHP
php通过执行CutyCapt命令实现网页截图的方法
2016/09/30 PHP
原生php实现excel文件读写的方法分析
2018/04/25 PHP
PHP中cookie知识点学习
2018/05/06 PHP
JS定时刷新页面及跳转页面的方法
2013/07/04 Javascript
extjs 分页使用jsp传递数据示例
2014/07/29 Javascript
Nodejs学习item【入门手上】
2016/05/05 NodeJs
AngularJs bootstrap搭载前台框架——js控制部分
2016/09/01 Javascript
Bootstrap面板(Panels)的简单实现代码
2017/03/17 Javascript
jquery网页加载进度条的实现
2017/06/01 jQuery
nodeJS进程管理器pm2的使用
2019/01/09 NodeJs
uni-app实现点赞评论功能
2019/11/25 Javascript
[01:19:34]2014 DOTA2国际邀请赛中国区预选赛 New Element VS Dream time
2014/05/22 DOTA
[36:19]2018DOTA2亚洲邀请赛 小组赛 A组加赛 Newbee vs LGD
2018/04/03 DOTA
[01:17]炒鸡美酒第四天TA暴走
2018/06/05 DOTA
PyCharm安装第三方库如Requests的图文教程
2018/05/18 Python
TensorFlow数据输入的方法示例
2018/06/19 Python
Python3读写Excel文件(使用xlrd,xlsxwriter,openpyxl3种方式读写实例与优劣)
2020/02/13 Python
python安装及变量名介绍详解
2020/12/12 Python
介绍一下Java中标识符的命名规则
2014/02/03 面试题
校园十佳歌手策划书
2014/01/22 职场文书
医院节能减排方案
2014/06/13 职场文书
2014年小学班主任工作总结
2014/11/08 职场文书
交通事故代理词范文
2015/05/23 职场文书
签约仪式致辞
2015/07/30 职场文书
2016年社会主义核心价值观心得体会
2016/01/21 职场文书
详解Redis瘦身指南
2021/05/26 Redis
Python自动化爬取天眼查数据的实现
2021/06/15 Python
Python人工智能之混合高斯模型运动目标检测详解分析
2021/11/07 Python