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 相关文章推荐
文本框中,回车键触发事件的js代码[多浏览器兼容]
Jun 07 Javascript
根据经纬度计算地球上两点之间的距离js实现代码
Mar 05 Javascript
js简单实现调整网页字体大小的方法
Jul 23 Javascript
JS实现物体带缓冲的间歇运动效果示例
Dec 22 Javascript
jQuery布局组件EasyUI Layout使用方法详解
Feb 28 Javascript
jQuery设置图片等比例缩小的方法
Apr 29 jQuery
JavaScript编写棋盘覆盖代码详解
Aug 28 Javascript
React通过父组件传递类名给子组件的实现方法
Nov 13 Javascript
Vue+element 解决浏览器自动填充记住的账号密码问题
Jun 11 Javascript
JS数组及对象遍历方法代码汇总
Jun 16 Javascript
vuecli项目构建SSR服务端渲染的实现
Oct 30 Javascript
jquery插件实现图片悬浮
Apr 16 jQuery
解决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实现将HTML5中Canvas图像保存到服务器的方法
2014/11/28 PHP
[原创]php使用curl判断网页404(不存在)的方法
2016/06/23 PHP
php 计算两个时间相差的天数、小时数、分钟数、秒数详解及实例代码
2016/11/09 PHP
thinkPHP5.0框架简单配置作用域的方法
2017/03/17 PHP
js获取通过ajax返回的map型的JSONArray的方法
2014/01/09 Javascript
jquery 表格排序、实时搜索表格内容(附图)
2014/05/19 Javascript
js操作iframe父子窗体示例
2014/05/22 Javascript
jQuery实现在下拉列表选择时获取json数据的方法
2015/04/16 Javascript
JQ实现新浪游戏首页幻灯片
2015/07/29 Javascript
如何使用jquery easyui创建标签组件
2015/11/18 Javascript
Bootstrap按钮组件详解
2016/04/26 Javascript
jQuery的ajax和遍历数组json实例代码
2016/08/01 Javascript
ThinkPHP+jquery实现“加载更多”功能代码
2017/03/11 Javascript
解决ie img标签内存泄漏的问题
2017/10/13 Javascript
微信小程序文字显示换行问题
2019/07/28 Javascript
layui 选择列表,打勾,点击确定返回数据的例子
2019/09/02 Javascript
微信小程序后端实现授权登录
2020/02/24 Javascript
Javascript执行流程细节原理解析
2020/05/14 Javascript
[01:02:25]2014 DOTA2华西杯精英邀请赛 5 24 iG VS DK
2014/05/26 DOTA
[03:49]显微镜下的DOTA2第十五期—VG登基之路完美团
2014/06/24 DOTA
[01:14:19]NAVI vs Mineski 2019国际邀请赛淘汰赛 败者组BO1 8.20.mp4
2020/07/19 DOTA
用Python输出一个杨辉三角的例子
2014/06/13 Python
Python中import机制详解
2017/11/14 Python
通过python+selenium3实现浏览器刷简书文章阅读量
2017/12/26 Python
对python 匹配字符串开头和结尾的方法详解
2018/10/27 Python
Python可变和不可变、类的私有属性实例分析
2019/05/31 Python
Python 测试框架unittest和pytest的优劣
2020/09/26 Python
HTML5实现晶莹剔透的雨滴特效
2014/05/14 HTML / CSS
园林毕业生自我鉴定范文
2013/12/29 职场文书
医药专业应届毕业生求职信范文
2014/01/01 职场文书
高三毕业典礼演讲稿
2014/05/13 职场文书
个人承诺书格式
2014/06/03 职场文书
法人委托书的范本格式
2014/09/11 职场文书
四风专项整治工作情况汇报
2014/10/28 职场文书
小学开学典礼新闻稿
2015/07/17 职场文书
Golang入门之计时器
2022/05/04 Golang