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

一 执行上下文?

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执行上下文顺序内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 浅析JavaScript作用域链、执行上下文与闭包

    闭包和作用域链是JavaScript中比较重要的概念,这两天翻阅了一些资料,把相关知识点给大家总结了以下. JavaScript 采用词法作用域(lexical scoping),函数执行依赖的变量作用域是由函数定义的时候决定,而不是函数执行的时候决定.以下面的代码片段举例说明,通常来说(基于栈的实现,如 C 语言) foo 被调用之后函数内的本地变量 scope 会被释放,但是从词法上看 foo 的内嵌匿名函数中 scope 应该指的是 foo 的本地变量 scope ,并且实际上代码的运行结

  • 通过实例了解JS执行上下文运行原理

    壹 ❀ 引 我们都知道,JS代码的执行顺序总是与代码先后顺序有所差异,当先抛开异步问题你会发现就算是同步代码,它的执行也与你的预期不一致,比如: function f1() { console.log('听风是风'); }; f1(); //echo function f1() { console.log('echo'); }; f1(); //echo 按照代码书写顺序,应该先输出 听风是风,再输出 echo才对,很遗憾,两次输出均为 echo:如果我们将上述代码中的函数声明改为函数表达式,结

  • 深入理解JavaScript系列(11) 执行上下文(Execution Contexts)

    简介 从本章开始,我将陆续(翻译.转载.整理)http://dmitrysoshnikov.com/网站关于ECMAScript标标准理解的好文. 本章我们要讲解的是ECMAScript标准里的执行上下文和相关可执行代码的各种类型. 原始作者:Dmitry A. Soshnikov 原始发布: 2009-06-26 俄文原文:http://dmitrysoshnikov.com/ecmascript/ru-chapter-1-execution-contexts/ 英文翻译:Dmitry A.

  • 跟我学习javascript的执行上下文

    在这篇文章里,我将深入研究JavaScript中最基本的部分--执行上下文(execution context).读完本文后,你应该清楚了解释器做了什么,为什么函数和变量能在声明前使用以及他们的值是如何决定的. 1.EC-执行环境或者执行上下文 每当控制器到达ECMAScript可执行代码的时候,控制器就进入了一个执行上下文(好高大上的概念啊). javascript中,EC分为三种: 全局级别的代码 –– 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境. 函数级别的代码

  • 一篇文章弄懂javascript中的执行栈与执行上下文

    前言 作为一个前端开发人员,弄清楚JavaScript的执行上下文有助于我们理解js中一些晦涩的概念,比如闭包,作用域,变量提升等等. 执行栈 执行栈用于存储代码执行期间创建的所有执行上下文.具有FILO接口,也被称为调用栈. 当JavaScript代码被运行的时候,会创建一个全局上下文,并push到当前执行栈.之后当发生函数调用的时候,引擎会为函数创建一个函数执行上下文并push到栈顶.引擎会先执行调用栈顶部的函数,当函数执行完成后,当前函数的执行上下文会被移除当前执行栈.并移动到下一个上下文

  • 深入探讨JavaScript的最基本部分之执行上下文

    在这篇文章中,我将深入探讨JavaScript的最基本部分之一,即Execution Context(执行上下文). 在本文结束时,你应该对解释器了解得更清楚:为什么在声明它们之前可以使用某些函数或变量?以及它们的值是如何确定的? 什么是执行上下文? JavaScript的执行环境非常重要,当JavaScript代码在行时,会被预处理为以下情况之一: Global code - 首次执行代码的默认环境. Function code - 每当执行流程进入函数体时. Eval code - 要在ev

  • 对于Javascript 执行上下文的全面了解

    在这篇文章中,将比较深入地阐述下执行上下文 – JavaScript中最基础也是最重要的一个概念.相信读完这篇文章后,你就会明白javascript引擎内部在执行代码以前到底做了些什么,为什么某些函数以及变量在没有被声明以前就可以被使用,以及它们的最终的值是怎样被定义的. 什么是执行上下文 Javascript中代码的运行环境分为以下三种: 全局级别的代码 – 这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境. 函数级别的代码 – 当执行一个函数时,运行函数体中的代码. Ev

  • 简单了解JavaScript中的执行上下文和堆栈

    什么是执行上下文? JavaScript的执行环境非常重要,当JavaScript代码在行时,会被预处理为以下情况之一: Global code - 首次执行代码的默认环境. Function code - 每当执行流程进入函数体时. Eval code - 要在eval函数内执行的文本. 你可以阅读大量涉及作用域的在线资料,不过为了使事情更容易理解,让我们将术语"执行上下文"视为当前代码的运行环境或作用域.接下来让我们看一个包含global和function / local上下文的代

  • 深入理解JavaScript 中的执行上下文和执行栈

    如果你是或者想成为一名 JavaScript 开发者,你必须知道 JavaScript 程序内部是如何执行的.理解执行上下文和执行栈对于理解其他 JavaScript 概念(如变量声明提升,作用域和闭包)至关重要. 正确理解执行上下文和执行栈的概念将使您成为更出色的 JavaScript 开发者. 闲话少说,让我们开始吧 :) 分享自 Bit的博客 使用 Bit 应用所提供的组件作为构建模块,你就是架构师.随时随地和你的团队分享.发现和开发组件,快来尝试鲜! Bit - 分享和创造代码组件: B

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

    一 执行上下文? 1什么是执行上下文? 执行上下文就是当前的 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行的. 2 执行上下文的类型 执行上下文分为三种类型: 全局执行上下文:只有一个,这是默认的,也是基础的执行上下文.(不在任何函数中的代码都是全局执行上下文)他有两个作用,一个是创建了全局变量,也就是指向window下的变量,另一个是将this的指向全局. 函数执行上下文:有无数个,每个函数都拥有自己的执行上下文,但

  • javascript执行上下文、变量对象实例分析

    本文实例讲述了javascript执行上下文.变量对象.分享给大家供大家参考,具体如下: 突然看到一篇远在2010年的老文,作者以章节的形式向我们介绍了ECMA-262-3的部分内容,主要涉及到执行上下文.变量对象.作用域.this等语言细节.内容短小而精悍,文风直白而严谨,读完有酣畅淋漓.醍醐灌顶之感,强烈推荐!!! 原文链接:这里 本想翻译成文,原来早已有人做了,这里.真生不逢时,何其遗憾啊! 做个笔记,聊慰我心. 执行上下文 ExecutionContext 每当控制器(control)转

  • JavaScript 执行上下文的视角详解this使用

    目录 前言 全局执行上下文中的 this 函数执行上下文中的 this this 的设计缺陷以及应对方案 1. 嵌套函数中的 this 不会从外层函数中继承 2. 普通函数中的 this 默认指向全局对象 window 前言 在对象内部的方法中使用对象内部的属性是一个非常普遍的需求.但是 JavaScript 的作用域机制并不支持这一点,基于这个需求,JavaScript 有另外一套 this 机制. this 是和执行上下文绑定的,也就是说每个执行上下文中都有一个 this.执行上下文主要分为

  • JavaScript 中的执行上下文和执行栈实例讲解

    JavaScript - 原理系列 ​ 在日常开发中,每当我们接手一个现有项目后,我们总喜欢先去看看别人写的代码.每当我们看到别人写出很酷的代码的时候,我们总会感慨!写出这么优美而又简洁的代码的兄弟到底是怎么养成的呢? ​ 我要怎样才能达到和大佬一样的水平呢!好了,废话不多说,让我们切入今天的主题. 一.执行上下文 ​ 简而言之,[执行上下文]就是JavaScript 代码被解析和执行时所在环境的抽象概念, 在JavaScript 中运行任何的代码都是在它的执行上下文中运行. ​ 在运行Java

  • JavaScript执行顺序详细介绍

    之前从JavaScript引擎的解析机制来探索JavaScript的工作原理,下面我们以更形象的示例来说明JavaScript代码在页面中的执行顺序.如果说,JavaScript引擎的工作机制比较深奥是因为它属于底层行为,那么JavaScript代码执行顺序就比较形象了,因为我们可以直观感觉到这种执行顺序,当然JavaScript代码的执行顺序是比较复杂的,所以在深入JavaScript语言之前也有必要对其进行剖析.1.1  按HTML文档流顺序执行JavaScript代码首先,读者应该清楚,H

  • 详解JavaScript中的执行上下文及调用堆栈

    一.执行上下文是什么 代码运行是在一定的环境之中运行的,这个运行环境我们就成为执行环境,也就是执行上下文,按照执行环境不同,我们可以分为三类: 全局执行环境:代码首次执行时候的默认环境 函数执行环境:每当执行流程进入到一个函数体内部的时候 Eval执行环境:当eval函数内部的文本执行的时候 二.执行上下文栈是什么 既然是'栈',那就得符合'栈'的特性,即数据结构是先进后出.下面我们看一段代码: function cat(a){ if(a<0){ return false; } console.

随机推荐