js一个关于作用域和执行环境的例子

在网上无意中看到一个关于js的作用域和执行环境的面试题,以前我也没怎么总是这些东西,经过一小段时间的研究,我慢慢开始明白其中的奥妙,这对以后写程序还是大有帮助的。日志代码如下:

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   if (g() && [] == ![]) { 
      f = function f() {return false;}; 
      function g() {return true;} 
   } 
})(); 
alert(f()); // true or false ?

可能大家一开始看到这个题目肯定都和我一样猜到了,最后输出的是false。那分析一下怎么得出结论的吧。



首先给大家脑补一下([] == ![])得到的应该是true。其中的缘由的家慢慢去领会吧。然后用这个例子给大家普及一点作用域链的知识。

在这段js代码执行下来的时候,会形成一条作用域链(我习惯把作用域链分层,可能这样不科学,但是有助于我们理解),在作用域链(第一层作用域链)的外层就是第1,2,9,还有整个3-8行的代码,在3-8行的代码内部又衍生出一条新的作用域链(第二层作用域链),在3-8行的内部,匿名函数function和它内部就是第二层作用域链。每一层都会有个执行环境,在下一层的执行环境里边可以访问上一层(或者更外层)执行环境中的变量,但是在上层执行环境中不能访问下一层执行环境中的私有变量(解决这个问题就要用闭包的思想)。



执行的第一阶段:在这个例子中的4行的if判断中执行的g()函数其实首先会在if所在当前层找有没有这个函数,如果没有,然后再顺着作用域链向上层寻找,因此首先会执行第6行的g()函数,返回true,因此,第一阶段的if判断为什么会返回true的疑惑就解决了。

执行的第二阶段:接下来就要执行if判断内部的代码了,在代码的第5行对前边的f()函数进行了重写(在f前边没有加var,因此就是覆盖全局的f变量),因此在内存中原本保存的f()函数就变了,应该返回false了,因此,内存中的f()改变,最后在第一层作用域中alert(f())就返回false。

时间: 2024-08-04 00:54:00

js一个关于作用域和执行环境的例子的相关文章

【JS】JavaScript中的执行环境与作用域

JavaScript中的执行环境定义了变量或函数有权访问的数据(每个函数都有自己的执行环境),全局执行环境是最外围的执行环境,在浏览器中,全局执行环境就是window对象,所以所有的全局变量和函数都是作为window对象的属性和方法创建的.当某一个执行环境中所有代码执行完成后,该环境就被销毁,保存在其中的变量和函数也将被销毁,全局执行环境在关闭网页或浏览器时才被销毁. 当代码在一个环境中执行时,会创建变量对象的一个作用域链(保证对执行环境有权访问的变量和函数的有序访问),如果环境是函数,将其活动

javascrip高级程序设计的学习笔记【作用域和执行环境】

javascript变量可以用来保存两种类型的值:基本类型和引用类型.基本类型包括以下5种:undefined.Null.string.Boolean.Number等, 引用类型是object:基本类型和引用类型都具有几下特点: 1.基本类型值在内存中占据固定大小的空间,因此基本类型的值被保存在栈内存中: 2.从一个变量向另一个变量复制基本类型的值,会创建这个值的副本. 3.引用类型的值是对象,保存在堆中: 4.包含引用类型值的变量实际并不是包含对象本身,而是一个指向该对象的指针: 5.从一个变

作用域、执行环境、闭包(四)

本文也同步发表在我的公众号"我的天空" 上一期我们已经介绍了闭包,由于闭包可以延长函数内部的变量的生存周期,因此我们可以将不需要暴露在全局的变量封装成函数的内部变量,从而避免代码污染. 譬如要实现一个简单的累加器,为了保存每次累加的结果,因此声明了一个全局变量total,代码如下: var total=0;function add(t){    total+=t;    alert(total);}total=2;add(3);        //显示5add(5);        /

JS高阶---作用域与执行上下文

一句话介绍 . 原文地址:https://www.cnblogs.com/jianxian/p/11971073.html

JavaScript 中的执行环境、作用域(scope)以及变量提升(hoisting)

先看下面一段代码: var a = 0; alert("1st alert : a = " + a); function fun(){ alert("2nd alert : a = " + a); var a = 1; setTimeout(function(){ alert("3rd alert : a = " + a); a = 2; },1000); a = 3; setTimeout(function(){ alert("4th

执行环境,作用域

在javascript的学习中,执行环境.作用域是2个非常非常重要和基本的概念,理解了这2个概念对于javsacript中很多脚本的运行结果就能明白其中的道理了,比如搞清作用域和执行环境对于闭包的理解至关重要. 一.执行环境(exection context,也有称之为执行上下文) 所有 JavaScript 代码都是在一个执行环境中被执行的.执行环境是一个概念,一种机制,用来完成JavaScript运行时在作用域.生存期等方面的处理,它定义了变量或函数是否有权访问其他数据,决定各自行为. 在j

深入理解javascript中执行环境(作用域)与作用域链

相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行环境分为全局执行环境和局部执行环境,其中局部执行环境我们又可以称之为函数执行环境.那么究竟什么使执行环境呢?通俗的说,执行环境即为代码执行时所处的环境.我们下来看一看如下代码,再进一步分析之. 1 2 3 4 5 6 7 8 9 10 11 <script><br>var name="zhuzhenwei"; functio

Javascript手记-执行环境和作用域

执行环境是javascript一个重要的概念,执行环境定义了变量有权访问其他数据决定了他们各自的行为,每个执行环境 都有一个与之关联的变量,环境中定义的所有变量和函数都保存在这个对象中,虽然我们编写的代码无法访问这个对象,但 解析器在处理数据时候会在后台使用. 全局执行环境是最外围的一个执行环境,根据ecmascript实现所在的宿主环境不同,表示执行环境的对象也不一样在 web浏览器中,全局执行环境被认为是window对象,因此所有的全局变量和函数都是作为window对象的属性和方法创建 的某

js中的作用域和作用域链

作用域1. 全局作用域2. 函数作用域这里扯出来下js的函数声明和变量声明提升,直接来两段代码 if (!a in window) { var a = 1; } console.log(a) //undefined 嗯,为什么呢?因为var声明的变量会变量声明提升,所以相当于执行if判断的时候a变量已经声明过了,而此时a是一个全局变量既是window对象的一个属性,所以这里压根没有进if判断,所以这里打印出来的是undefined再来一段坑坑的代码 (function (){ var a = b