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

一、JavaScript中无块级作用域

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

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

Java中

public static void Main()
{
if(1==1){
string name = "seven";
}
Console.WriteLine(name);
}
// 报错 C#

C#中

在JavaScript语言中无块级作用域

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

二、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中的作用域链执行前已创建

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。

【html、CSS、javascript-8】JavaScript作用域的更多相关文章

  1. 图解Javascript上下文与作用域

    原文网址:http://blog.rainy.im/2015/07/04/scope-chain-and-prototype-chain-in-js/ 本文尝试阐述Javascript中的上下文与作用 ...

  2. 【repost】图解Javascript上下文与作用域

    本文尝试阐述Javascript中的上下文与作用域背后的机制,主要涉及到执行上下文(execution context).作用域链(scope chain).闭包(closure).this等概念. ...

  3. 梅须逊雪三分白,雪却输梅一段香——CSS动画与JavaScript动画

    CSS动画并不是绝对比JavaScript动画性能更优越,开源动画库Velocity.js等就展现了强劲的性能. 一.两者的主要区别 先开门见山的说说两者之间的区别. 1)CSS动画: 基于CSS的动 ...

  4. Javascript之变量作用域

    分析: 无论是强类型语言c#.c++.java等语言,还是弱类型语言如Javascript,所有变量可以抽象为两种类型,即局部变量和全局变量. 全局变量:整个作用域可见. 局部变量:局部可见,退出作用 ...

  5. 深入理解 JavaScript 变量的作用域和作用域链

    一个变量的作用域(scope)是程序源代码中定义这个变量的区域.简单的说,作用域就是变量与函数的可访问范围.全局变量拥有全局作用域,在JavaScript代码中的任何地方都有定义.局部变量是在函数体内 ...

  6. javascript变量的作用域

    javascript变量的作用域 基本类型和引用类型 基本类型值指的是简单的数据段,而引用类型值指的是那个可能由多个值组成的对象  讲一个值赋值给变量时,javascript解析器首先要确定是基本类型 ...

  7. [转]深入理解JavaScript的变量作用域

    1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...

  8. JavaScript中的作用域

    很多(JavaScript)开发者都在讨论"作用域",但它是什么?它们在JavaScript中的任何地方!我发现很多年轻的开发者不知道作用域是什么.他们中大多数人可以用jQuery ...

  9. javascript篇-----函数作用域,函数作用域链和声明提前

    在一些类似C语言的编程语言中,花括号内的每一段代码都具有各自的作用域,而且变量在声明它们的代码段之外是不可见的(也就是我们不能在代码段外直接访问代码段内声明的变量),我们称之为块级作用域,然而,不同于 ...

  10. javascript笔记:javascript的关键所在---作用域链

    javascript里的作用域是理解javascript语言的关键所在,正确使用作用域原理才能写出高效的javascript代码,很多javascript技巧也是围绕作用域进行的,今天我要总结一下关于 ...

随机推荐

  1. umount:将文件设备卸载

    [root@centos57 ~]# umount /dev/hda1 用设备文件名来卸载 [root@centos57 ~]# umount /aixi                     用挂 ...

  2. ng-zorro-mobile中遇到的问题

    一.Modal(弹出框)使用上的问题 在官方文档中,Modal是这样使用的: 这里需要注意的一点就是,看到上方代码中只用了Modal的全局方式,所以个人认为下面这段注入初始化的东西是没有用的便去掉: ...

  3. bzoj1913: [Apio2010]signaling 信号覆盖

    传送门 题解传送门 //Achen #include<algorithm> #include<iostream> #include<cstring> #includ ...

  4. javaweb的几种开发模式

    1.MVC模式基础 1.1.MVC模式简介 MVC是一种架构型模式,它本身并不引入新的功能,只是用来指导我们改善应用程序的架构,使得应用的模型和视图相分离,从而达到更好的开发和维护效率.在MVC模式中 ...

  5. Docker系列(十五):Openshift 简介

    1.简单了解openshift相关组件 1.openshift是基于容器技术构建的一个云平台 2.kubernetes是容器编排组件 3.docker是容器引擎驱动组件 4.openshift在Pas ...

  6. 模板——网络流Dinic

    感谢这位大佬的博客:https://www.cnblogs.com/SYCstudio/p/7260613.html 给予了我莫大的帮助! 主要说一下网络流的几个注意点: 1.和二分图匹配相似,无法继 ...

  7. CF #575 Div3

    // 比赛链接:https://codeforces.com/contest/1196 // CF 2019.7.24 // 本想Div3手速场上分,结果卡在C题,掉了不少分. // 自闭了这么久,今 ...

  8. Django入门之基础篇01

    这是第一篇Django(花音:浆够)入门博客,学习Django的初衷是为了开发自己的个人小小网站(虽然有了博客园,还是想建立自己的博客,因为自主定制,香香香~!)

  9. mariadb ROW格式复制下从库结构变更引发1677错误

    stop slave;set global slave_type_conversions=ALL_LOSSY;start slave; 详细度娘slave_type_conversions的参数说明

  10. Activiti 接收任务活动

    流程中往往需要特定人接受任务并进行一定操作才能继续进行下去. 代码如下 import java.io.InputStream; import org.activiti.engine.ProcessEn ...