JavaScript作用域(链)学习笔记

     作用域是javascript老生常谈的问题,在面试题中也经常出现。此文记录本人对js作用域的理解。从以下三个方面深入探讨js作用域和js作用域链。

  1、什么是作用域?

  2、什么是作用域链?

  3、常见面试题。

  

  一、什么是作用域?

    熟悉编程的人都接触过作用域,比如全局变量和局部变量之分。作用域是变量和函数可以访问的范围,即作用域控制着变量和函数的可见性和生命周期。

var name = "Aralic";
function person () {
    //局部变量
    var age = "22";

    console.log(country) // "china"
    console.log(name);  //  ‘Aralic‘
    console.log(age);   //   22
}

person();    

在这段代码中,函数person就创建一个作用域,作用域里面定义了一个变量age,在函数person外面是无法访问这个变量的。但是在函数person内部是可以访问到变量name,

因为name是函数person外面定义的,相对函数person是全局变量。

  二、什么是作用域链?

    其实上面的例子已经出现了作用域链了。本来想画图解释的,可惜画图功底实在太差了。还是上代码吧。

var country = "china";
function china () {
  var name = "Aralic";
  function person () {
    //局部变量
    var age = "22";

    console.log(country) // "china"
    console.log(name);  //  ‘Aralic‘
    console.log(age);   //   22
  }

  person();
}

china ();

在函数person中,访问country的过程:先从函数内部找,发现没有country这个变量,那玩外层函数china找,结果还是没有找到,那继续往外找,结果找到了,不容易啊,嘿嘿,那这就是作用域链,一环扣一环,很厉害,有木有!

扩展:看到这里,有小伙伴就要问了,假如在函数person里面也定义一个变量country=“American”,那结果会是怎么样?会不会变量冲突?

大声告诉你,不会冲突,结果就是直接打印出来American。不会向外层查找了。这样就形成了一条完整的作用域链,如果找到浏览器顶层window还没有访问到目标变量和函数,

那直接返回脚本错误!

性能相关小技巧: 如果函数嵌套比较深,那么我们在最里面函数中用原生方法比如,document.getElementById(id); 那么这个document我们是不是需要一层一层向外查找,

那考虑到性能问题,我们是不是可以直接在函数里面把document赋值给一个变量,那每次只要访问这个变量就终止查找了!

     三、常见面试题:

  我们已经学习了作用域和作用域链的知识,那么下面来看几个面试题。

第一题:

var  name = "Aralic";

function person () {
   console.log(name);
   var name = "Aralic";  
}

person();

博主第一次见到这个题目的时候,以为答案是Aralic,有没有人和我想的一样的?

在函数执行前,javascript存在预编译过程。

当调用函数person的时候会先预编译,把变量和函数声明提升,转成

function person () {

  var name; //不赋初始值

  console.log(name);// 输入undefined

  var name = "Aralic";

  console.log(name) // 输出Aralic

}

person ();

第二题:

  var name = ‘Aralic‘;
  function person() {
        console.log(name);
   }

   function test() {
       var name = ‘tom‘;
       person();
   }

   test();

这个题目看起来有点绕,先执行test函数,然后在test函数里面调用person函数,执行person函数,打印name变量,那到底name变量是从test函数里面找,还是直接访问最外面的name全局变量。这个题目和作用域链有关,说起来,person和test函数地位是相同的,所以是直接从最外面找name。

更多相关问题:请阅读《单页web应用》第二章节,讲的比较详细。

时间: 2024-10-09 11:44:41

JavaScript作用域(链)学习笔记的相关文章

Javascript高级程序设计学习笔记

3. 基本概念 基本数据类型:Undefined,Null,Boolean,Number,String. 复杂数据类型:Object. 3.6 语句 switch比较值时用的是全等运算符 “===” ,因此不会进行类型转换.例如 “10” 不等于10. 3.7 函数 ECMAScript函数不介意传递进来多少个参数,也不在乎参数的类型.即使定义的函数只接受两个参数,在调用的时候也可以传递任意多个或者0个.因为ECMAScript的参数在内部是用一个数组表示的,在函数体内部可以通过argument

JavaScript高级程序设计学习笔记--基本概念

1.语句 ECMAScript中的语句以一个分号结尾:如果省略分号,则由解析器确定语句的结尾,如下例所示: var sum=a+b //即使没有分号也是有效的语句--推荐 var diff=a-b; //有效的语句--推荐 虽然语句结尾的分号不是必需的,但我们建议任何时候都不要省略它.两个原因:1.加上分号可以避免很多错误 2.加上分号也会在某些情况下增进代码的性能,因为这样解析器就不必再花时间 推测应该在哪里插入分号了. 2.变量 var message="hi"; 像这样初始化变量

JavaScript高级程序设计学习笔记--DOM

DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序接口). Document类型 文档的子节点 虽然DOM标准规定Document节点的子节点可以是DocumentType,Element,ProcessingInstruction或Comment,但还有两个内置的访问其子节点的快捷方式.第一个就是documnetElement属性,该属性始终指向HTML页面中的<html>元素.另一个就是通过childNodes列表访问文档元素,但通过documentElement属性则

JavaScript高级程序设计学习笔记--BOM

window对象 BOM的核心对象是window,它表示浏览器的一个实例.在浏览器中,window对象有双重角色,它既是通过JavaScript访问浏览器窗口的一个接口,又是ECMScript规定的Global对象. 全局作用域 由于window对象同时扮演着ECMAScript中Global对象的角色,因此所有在全局作用域中声明的变量.函数都会变成window对象的属性和方法.来看下面的例子: var age=29; function sayAge(){ alert(this.age); }

JavaScript高级程序设计学习笔记--引用类型

Object类型 对象字面量表示法: var person={ name:"Nicholas", age:29, 5:true }; 这人例子会创建一个对象,包含三个属性:name,age和5.但这里的数值属性名会自动转换为字符串. 对象属性的访问:点表示法和方括号语法 alert(person["name"]); // "Nicholas" alert(person.name); // "Nicholas" 从功能上看,这两

JavaScript作用域链

JavaScript作用域链 之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时候发现作用域和执行环境确实很重要,又很基础,对理解JavaScript闭包很有帮助,所以在写一篇对作用域和执行环境的理解. 作用域 作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域. 单纯

JavaScript高级程序设计学习笔记--错误处理与调试

try-catch语句 只要代码中包含finally子句,则无论try或catch语句块中包含什么代码--甚至return语句,都不会阻止finally子句的执行,来看下面这个函数: function testFinally(){ try{ return 2; }catch(error){ return 1; }finally{ return 0; } } 调用这个函数会返回0(PS:但我实际执行的时候会先返回0,再返回2) 抛出错误 与try-catch语句相配的还有一个throw操作符,用于

JavaScript 作用域链图详解

<script type="text/javascript"> /** * 作用域链: */ var a = "a"; function hao947(){ var b = "b"; alert(a);// output a alert(b);// output b // alert(c);// output undefind function hao(){ var c = "c"; alert(a);// out

ArcGIS API for JavaScript 4.2学习笔记[0] AJS4.2概述、新特性、未来产品线计划与AJS笔记目录

放着好好的成熟的AJS 3.19不学,为什么要去碰乳臭未干的AJS 4.2? 诸君,我喜欢嫩的--呸呸呸 诸君,我喜欢3D咋了?新事物会替代旧事物不是~ ArcGIS API for JavaScript 4.2概述 AJS 4.2,即ArcGIS API for JavaScript 4.2,是美国ESRI公司针对WebGIS市场推出的.利用JavaScript和Dojo开发的一款产品,它在2016年12月发布.而AJS 4.0 beta则在一年前就发布了. 关于AJS3和AJS4选择的问题,