资讯专栏INFORMATION COLUMN

深入理解 Javascript 之 作用域

banana_pi / 1060人阅读

摘要:作用域是门动态语言,跟不一样,可以随意定义全局变量和局部变量,变量会在该作用域下提升,而且没有块级作用域。一预处理作用域解析的作用域只用两种,一个是全局的,一个是函数的,也称为全局作用域和局部作用域局部作用域可以访问全局作用域。

作用域
JavaScript是门动态语言,跟Java不一样,JavaScript可以随意定义全局变量和局部变量,变量会在该作用域下提升,而且JavaScript没有块级作用域。
全局变量就是定义在全局的变量了,局部变量是定义在函数里的变量,每一个函数都是一个作用域,当函数执行时会优先查找当前作用域,然后逐级向上。定义在
if 和 for 语句里的变量,在大括号外面也能访问到,这就是没有块级作用域。

一、预处理 + 作用域解析

JavaScript 的作用域只用两种,一个是全局的,一个是函数的,也称为 全局作用域 和 局部作用域 ;局部作用域 可以访问 全局作用域 。但是 全局作用域 不能访问 局部作用域

有这样一段代码

var a = 1;
function fn1(){
    alert(a);
    var a = 2;
}
fn1();
alert(a);

这里先揭晓答案:

第一个 alert(a) 弹出 undefined
第二个 alert(a) 弹出 1

1. 预解析(预编译) 全局作用域 (全局词法环境)

// 全局词法环境
// 第1行,遇到 var 关键字,解析到全局的头部
a = undefined
// 第2行,遇到 function 关键字,解析到全局的头部
fn1 = function fn1(){
    alert(a);
    var a = 2;
}
// 第3行,没有遇到关键字,不解析
// 第4行,没有遇到关键字,不解析

2. 开始执行代码

第1行,遇到表达式 a = 1, a 被赋值成 1 
第6行,遇到函数调用 fn1() ,           ---- 开始 预解析(预编译) 局部-----

3. 预解析(预编译) 局部作用域 (函数词法环境)

// 第3行,没有遇到关键字,不解析
// 第4行,遇到 var 关键字,解析到局部
a = undefined

4. 开始执行 局部 代码

第3行,弹出 undefined
第4行,遇到表达式,把局部 a 改成 2

5. 局部执行完成,继续执行全局

第7行,弹出 1 ,因为全局和局部是两个独立的作用域
二、作用域疑惑之处

1. js没有块作用域

2. js不是动态作用域,js是静态作用域

function f(){
  alert(x);
}
function f1() {
  var x = 6;
  f();
}
function f2() {
  var x = 10;
  f();
}

f1();
// 执行会报错,因此js不是动态作用域哦
二、作用域链
var a = 10;

function f() {
  var x = 100;
  function g () {
    // 
  }
  g();
}
f();

作用域链解析

1. 创建词法环境(window)
2. 加入 a 以及 f函数 ,这时候     【f.scope === window】
3. 进入f函数,创建f函数的词法环境  【f.le => f.scope】
4. 创建f 的词法环境 
5. 添加x和 g函数 到f函数的词法环境 【g.scope === f.le】
6. 进入g函数,创建g函数的词法环境  【g.le => g.scope】
g.le  ->  g->scope  ->  f.le  ->  f.scope  ->  window
三、作用域的本质
var a = 10;

function f() {
  var x = 100;
  function g () {
    // 
    alert(a);
  }
  g();
}
f();

我们在g内部使用了变量a,想要找到a,

首先在g的词法环境中查找,如果没找到

到g.scope 也就是 f的词法环境中查找,如果依旧没找到

到f.scope 也就是 全局词法环境中查找。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96754.html

相关文章

  • 【进阶2-2期】JavaScript深入作用理解闭包

    摘要:使用上一篇文章的例子来说明下自由变量进阶期深入浅出图解作用域链和闭包访问外部的今天是今天是其中既不是参数,也不是局部变量,所以是自由变量。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第二期,本周的主题是作用域闭包,今天是第7天。 本计划一共28期,每期重点攻克一个面试重难点,如果你还不了解本进阶计...

    simpleapples 评论0 收藏0
  • 【进阶2-3期】JavaScript深入闭包面试题解

    摘要:闭包面试题解由于作用域链机制的影响,闭包只能取得内部函数的最后一个值,这引起的一个副作用就是如果内部函数在一个循环中,那么变量的值始终为最后一个值。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第二期,本周的主题是作用域闭包,今天是第8天。 本计划一共28期,每期重点攻克一个面试重难点,如果你还不了...

    alanoddsoff 评论0 收藏0
  • 深入学习js——作用

    摘要:开篇作用域是每种计算机语言最重要的基础之一,因此要想深入的学习作用域和作用域链就是个绕不开的话题。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。这时候执行上下文的作用域链,我们命名为至此,作用域链创建完毕。 开篇 作用域是每种计算机语言最重要的基础之一,因此要想深入的学习JavaScript,作用域和作用域链就是个绕不开的话题。 在《深入学习js之—-执行上下文栈》中我们提到...

    lemanli 评论0 收藏0
  • JavaScript深入作用

    摘要:下面,让我们以一个函数的创建和激活两个时期来讲解作用域链是如何创建和变化的。这时候执行上下文的作用域链,我们命名为至此,作用域链创建完毕。 JavaScript深入系列第五篇,讲述作用链的创建过程,最后结合着变量对象,执行上下文栈,让我们一起捋一捋函数创建和执行的过程中到底发生了什么? 前言 在《JavaScript深入之执行上下文栈》中讲到,当JavaScript代码执行一段可执行代...

    waltr 评论0 收藏0
  • 深入学习js——词法作用和动态作用

    摘要:在中的应用采用词法作用域,也就是静态作用域。那什么又是词法作用域或者静态作用域呢请继续往下看静态作用域与动态作用域因为采用的是词法作用域函数的作用域在函数定义的时候就决定了。 开篇 当我们在开始学习任何一门语言的时候,都会接触到变量的概念,变量的出现其实是为了解决一个问题,为的是存储某些值,进而,存储某些值的目的是为了在之后对这个值进行访问或者修改,正是这种存储和访问变量的能力将状态给...

    shiweifu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<