JavaScript的作用域一直以来是前端开发中难以理解的知识点,对于JavaScript的作用域主要记住几句话。

一、“JavaScript” 中无块级作用域

在   Java 或 C# 中存在块级作用域,即:大括号也是一个作用域。

 public static void main ()
{
if(1==1){
String name = "seven";
}
System.out.println(name);
}
// 报
public static void Main()
{
if(1==1){
string name = "seven";
}
Console.WriteLine(name);
}
// 报错

C#

在JavaScript 语言中无块级作用域

 function Main(){
if(1==1){
var name = 'seven';
}
console.log(name);
}
// 输出: seven

补充: 标题之所以添加双影号是因为javascript6中新引入了let关键字,用于指定变量属于块级作用域。

二、JavaScript 采用函数作用域

在 JavaScript 中每个函数作为一个作用域,在外部无法访问内部作用域中的 变量。

 function Main(){
var innerValue = 'seven';
} Main(); console.log(innerValue); // 报错:Uncaught ReferenceError: innerValue is not defined

三、JavaScript 的作用域链

由于 JavaScript 中的每个函数 作为一个作用域,如果出现函数嵌套函数,则就会出现作用域链。

 xo = 'alex';

 function Func(){
var xo = "seven";
function inner(){
var xo = 'alvin';
console.log(xo);
}
inner();
}
Func();

如上述代码则出现三个作用域组成的作用域链,如果出现作用域链后,那么寻找变量的时候就会出现顺序,对于上述实例:

当执行 console.log( xo) 时,其寻找顺序 为根据作用域链从内到外的优先级寻找,如果内层没有就逐步向上找,直到没有抛出异常。

四、JavaScript 的作用域链执行前已创建,日后再去执行时只需要按照作用域链去寻找即可。

示例一

 xo = 'alex';

 function Func(){
var xo = "seven";
function inner(){ console.log(xo);
}
return inner;
} var ret = Func();
ret();
// 输出结果: seven

上述代码,在函数被调用之前作用域已经存在:

全局作用域 ->  Func函数作用域  ->  inner函数作用域

当执行【ret();】 时,由于其指代的是 inner函数,此函数作用域链在执行之前已经被定义为  全局作用域 ->  Func函数作用域  ->  inner函数作用域。 所以,在执行【ret();】时,会根据已经存在的作用域的作用域链去寻找变量。

示例二

 xo = 'alex';

 function Func(){
var xo = "eirc";
function inner(){ console.log(xo);
}
xo = 'seven';
return inner;
} var ret = Func();
ret();
// 输出结果: seven

上述代码和示例一的目的相同,也是强调在函数被调用之前作用域链已经存在:

  • 全局作用域 -> Func函数作用域 -> inner函数作用域

不同的时,在执行【var ret = Func();】时,Func作用域中的xo变量的值已经由 “eric” 被重置为 “seven”,所以之后再执行【ret();】时,就只能找到“seven”。

示例三:

 xo = 'alex';<br>
function Bar(){
console.log(xo);
} function Func(){
var xo = "seven"; return Bar;
} var ret = Func();
ret();
// 输出结果: alex

上述代码,在函数被执行之前已经创建了两条作用域链:

  • 全局作用域 -> Bar函数作用域
  • 全局作用域 -> Func函数作用域

当执行【ret();】时,ret代指的Bar函数,而Bar函数的作用域链已经存在:全局作用域 -> Bar函数作用域,所以,执行时会根据已经存在的作用域链去寻找。

五、声明提前

在JavaScript中如果不创建变量,直接去使用,则报错:

 console.log(xxoo);
// 报错:Uncaught ReferenceError: xxoo is not defined

JavaScript中如果创建值而不赋值,则该值为 undefined,如:

 var xxoo;
console.log(xxoo);
// 输出:undefined

在函数内如果这么写:

 function Foo(){
console.log(xo);
var xo = 'seven';
} Foo();
// 输出:undefined

上述代码,不报错而是输出 undefined,其原因是:JavaScript的函数在被执行之前,会将其中的变量全部声明,而不赋值。所以,相当于上述实例中,函数在“预编译”时,已经执行了var xo;所以上述代码中输出的是undefined。

 

JavaScript 作用域知识点梳理的更多相关文章

  1. Javascript重要知识点梳理

    Javascript重要知识点梳理 一.Javascript流程控制 js中常用的数据类型 var关键字的使用 if – else if – else switch while for 二.Javas ...

  2. JavaScript基础知识梳理,你能回答几道题?

    在学习JavaScript的时候,总是这里学一点,那里学一点,很的很零星,很杂,没有很系统的去学习,感觉好像JavaScript的知识点都了解了,但是真正要说起来,又不知道从何说起! 最深刻的体会就是 ...

  3. Python自动化 【第十六篇】:JavaScript作用域和Dom收尾

    本节内容: javascript作用域 DOM收尾 JavaScript作用域 JavaScript的作用域一直以来是前端开发中比较难以理解的知识点,对于JavaScript的作用域主要记住几句话,走 ...

  4. JavaScript作用域学习笔记

    重点知识点摘要 一 函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性 其中一个内部属性是[[Scope]],由ECMA-262标准第三版定义,该内部 ...

  5. 读《你不知道的JavaScript(上卷)》后感-浅谈JavaScript作用域(一)

    原文 一. 序言 最近我在读一本书:<你不知道的JavaScript>,这书分为上中卷,内容非常丰富,认真细读,能学到非常多JavaScript的知识点,希望广大的前端同胞们,也入手看看这 ...

  6. 由浅入深,66条JavaScript面试知识点

    前言 我只想面个CV工程师,面试官偏偏让我挑战造火箭工程师,加上今年这个情况更是前后两男,但再难苟且的生活还要继续,饭碗还是要继续找的.在最近的面试中我一直在总结,每次面试回来也都会复盘,下面是我这几 ...

  7. JavaScript进阶知识点——函数和对象详解

    JavaScript进阶知识点--函数和对象详解 我们在上期内容中学习了JavaScript的基本知识点,今天让我们更加深入地了解JavaScript JavaScript函数 JavaScript函 ...

  8. JavaScript作用域

    JavaScript作用域 JavaScript作用域一直是前端开发的难题,现在只要用五句话就可解决. 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个 ...

  9. 关于Javascript作用域及作用域链的总结

    本文是根据以下文章以及<Javascript高级程序设计(第三版)>第四章相关内容总结的. 1.Javascript作用域原理,地址:http://www.laruence.com/200 ...

随机推荐

  1. iOS 事件传递(Touch事件)

    先总说如下: 1.当手指触摸到屏幕时,会产生UITouch对象和UIEvent对象. 2.这两个对象产生后会被传递到UIApplication管理的一个事件队列中. 3.再有UIApplication ...

  2. C# IEnumberable & IQueryable 区别

    转自 http://blog.csdn.net/daimeisi123/article/details/46976093 在应用到IEnumberable 和IQueryable两个接口时,代码往往很 ...

  3. Reason: image not found

    刚生的Xcode8,出现好多Error,有些Error真的太麻烦不想记录,现在这个挺简单的,就记下来,控制台输出的Error信息如下: fix: Target -> Build Phases - ...

  4. Object-c 类方法和实例方法的区别和联系

    在我学习oc的时候,总是搞不懂什么时候用类方法,什么时候使用实例方法.于是做了如下总结. -表示实例方法: 用实例方法访问 +表示类方法:类方法的对象时类不是实例.多用于创建对象或工具类 什么时候使用 ...

  5. iOS之中途修改类名

    中途修改类名 在开发过程中,可能感觉之前设置的类名不够代表性,或者发现名字拼写错误等等诸如此类的原因,需要修改类名,不懂技巧的话简直不敢改,现在这里就记录下该类名的方法. 具体步骤如下: .h文件里选 ...

  6. mysql 数据库连接超时的问题 autoReconnect=true

    最近在使用spring-jdbc数据库连接管理时,出现一个奇怪问题,当天部署运行没问题,第二天再试就报以下异常问题 org.springframework.dao.RecoverableDataAcc ...

  7. 纯css实现二级导航菜单效果,通过简单的鼠标事件操作页面元素样式变换实现二级导航菜单的功能,非常简单实用,

    HTML代码如下 <!-- 头部导航栏开始--><div id="nav"><dl class="sy"><dt> ...

  8. Linux系统目录结构以及简单说明

    Linux系统目录结构以及简单说明 linux目录图: / root --- 启动Linux时使用的一些核心文件.如操作系统内核.引导程序Grub等. home --- 存储普通用户的个人文件 ftp ...

  9. Hadoop中的问题排查思路

    一.概述: 在实际使用hadoop的过程中,由于涉及到多台服务器.每台机器上可能还有多个服务等.所以当集群环境出现问题时,快速定位到错误出现的地方尤为重要. 在排查错误的过程中,基本上就是通过既有的工 ...

  10. 转:SqlServer2012自增列值突然增大1000的原因及解决方法

    原文链接:http://blog.csdn.net/phoenix36999/article/details/53304126 首先排除数据回滚及增加删除等操作. 按照这篇文章SQL Server 2 ...