JavaScript作用域示例详解

作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理。今天这篇文章对JavaScript作用域示例详解的介绍,希望能帮助大家更好的学习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);
}
// 报错 

在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。

以上所述是小编给大家介绍的JavaScript作用域示例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • 深入浅析JavaScript中的作用域和上下文

    javascript中的作用域(scope)和上下文(context)是这门语言的独到之处,这部分归功于他们带来的灵活性.每个函数有不同的变量上下文和作用域.这些概念是javascript中一些强大的设计模式的后盾.然而这也给开发人员带来很大困惑.下面全面揭示了javascript中的上下文和作用域的不同,以及各种设计模式如何使用他们. 上下文(Context)和作用域(Scope) 首先需要知道的是,上下文和作用域是两个完全不同的概念.多年来,我发现很多开发者会混淆这两个概念(包括我自己),

  • 深入理解javascript作用域第二篇之词法作用域和动态作用域

    前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极易出错.这实际上是由两种作用域工作模型导致的,作用域分为词法作用域和动态作用域,分清这两种作用域模型就能够对变量查找过程有清晰的认识.本文是深入理解javascript作用域系列第二篇--词法作用域和动态作用域 词法作用域 第一篇介绍过,编译器的第一个工作阶段叫作分词,就是把由字符组成的字符串分解成词法单元.这个概念是理解词法作用域

  • 轻松5句话解决JavaScript的作用域

    javascript 程序的每一个字节都是在这个或那个运行上下文(execution context)中执行的.你可以把这些上下文想象为代码的邻居,它们可以给每一行代码指明:从何处来,朋友和邻居又是谁.没错,这是很重要的信息,因为 javascript社会有相当严格的规则,规定谁可以跟谁交往.运行上下文则是有大门把守的社区而非其内开放的小门. 我们通常可以把这些社会边界称为作用域,并且有充足的重要性在每一位邻居的宪章里立法,而这个宪章就是我们要说的上下文的作用域链(scope chain).在特

  • 为什么JavaScript没有块级作用域

    最近在看ES2015 实战,里面有句话是这么说的 JavaScript 中没有块级作用域 可能会对这个问题大家可能有点不理解,先看个例子 var a = [] for(var i = 0; i < 10; i++){ a[i] = function(){ console.log(i); } } a[6](); 我想很多人会觉得这个问题的结果是6,然而很不幸,答案是10.在试试别的呢.a[7]().a[8]().a[8]()结果都是10!! 由于JS在处理primitive的变量的时候,很多时候会

  • 深入浅析javascript中的作用域(推荐)

    所谓的作用域,可以简单理解为一个可以读.写的范围(区域),有些js经验的同学可能会说:"js没有块级作用域",js除了全局作用域外,只有函数可以创建作用域.作用域的一个好处就是可以隔离变量. 我们通过一些例子来帮助我们理解js中的作用域. alert(a); var a = 1; 如果对作用域一点不了解的同学可能会说 alert的是1或者报错:但实际上是undefined: 说到这里,我们首先说一下js逐行解析代码之前做的一些准备工作, js在逐行读代码之前,会做一些"预解析

  • JavaScript中用let语句声明作用域的用法讲解

    语法 let variable1 = value1 参数 variable1 要声明的变量的名称. value1 赋给变量的初始值. 备注 使用 let 语句声明一个变量,该变量的范围限于声明它的块中.  可以在声明变量时为变量赋值,也可以稍后在脚本中给变量赋值.  使用 let 声明的变量,在声明前无法使用,否则将会导致错误. 如果未在 let 语句中初始化您的变量,则将自动为其分配 JavaScript 值 undefined. 示例: var l = 10; { let l = 2; //

  • 谈一谈js中的执行环境及作用域

    最近在面试时被问到了对作用域链的理解,感觉当时回答的不是很好,今天就来说说js中的作用域链吧. 首先来说说js中的执行环境,所谓执行环境(有时也称环境)它是JavaScript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据 ,决定了它们各自的行为.而每个执行环境都有一个与之相关的变量对象,环境中定义的所有变量和函数都保存在这个对象中. 理解了执行环境,现在就看看什么是作用域链吧.每个函数都有自己的执行环境,当代码在执行环境中执行时,就会创建变量对象的作用域链.作用域链保证了对执

  • javascript执行环境及作用域详解

    最近在重读<javascript高级程序设计3>,觉得应该写一些博客记录一下学习的一些知识,不然都忘光啦.今天要总结的是js执行环境和作用域. 首先来说一下执行环境 一.执行环境         书上概念,执行环境定义了变量或者函数有权访问的其他数据,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象.环境中定义的所有变量和函数都保存在这个对象中.虽然我们在编写代码的时候无法访问这个对象,但解析器在处理数据时会在后台用到它. 执行环境是一个概念,一种机制,它定义了变量或函数是否有权访

  • JavaScript作用域示例详解

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理.今天这篇文章对JavaScript作用域示例详解的介绍,希望能帮助大家更好的学习JavaScript. 任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期.在JavaScript中,变量的作用域有全局作用域和局部作用域两种. 一.JavaScript中无块级作用域 在Java或C#中存在块级作用域

  • C/C++中的名字空间与作用域示例详解

    前言 本文主要给大家介绍了关于C/C++中名字空间与作用域的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. C语言中有名字空间这个概念吗? 提到名字空间(或者可能更普遍的叫法,命名空间),很可能先想到的是C++,甚至是C#.C中没有名字空间吧?一开始我也是这样认为的,直到我看了C primer plus这本书,才直到C语言中其实也有名字空间的概念!而为什么我们更熟悉C++中的名字空间呢?可能是因为我们一些C++程序,不过知不知道为什么,总是要加上一句using nam

  • JavaScript代码优化技巧示例详解

    目录 引言 提炼函数 函数参数化 使用策略模式替换“胖”分支 提炼变量 内联变量 封装变量 拆分阶段 拆分循环 拆分变量 分解条件表达式 合并条件表达式 以卫语句取代嵌套条件表达式 将查询函数和修改函数分离 引言 我们先引入一句话: 代码主要是为了写给人看的,而不是写给机器看的,只是顺便也能用机器执行而已. 代码和语言文字一样是为了表达思想.记载信息,所以写得清楚能更有效地表达.本文多数总结自<重构:改善既有代码的设计(第2版)>我们直接进入正题,上代码! 提炼函数 what 将一段代码提炼到

  • JavaScript中自带的 reduce()方法使用示例详解

    1.方法说明 , Array的reduce()把一个函数作用在这个Array的[x1, x2, x3...]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,其效果就是: [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4) 2. 使用示例 'use strict'; function string2int(s){ if(!s){ alert('the params empty'); return; } if

  • JavaScript中的ajax功能的概念和示例详解

    AJAX即"Asynchronous Javascript And XML"(异步JavaScript和XML). 个人理解:ajax就是无刷新提交,然后得到返回内容. 对应的不使用ajax时的传统网页如果需要更新内容(或用php做处理时),必须重载整个网页页面. 示例: html代码如下 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>

  • 常用JavaScript正则表达式汇编与示例详解

    1.1 前言 目前收集整理了21个常用的javaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份证号.URL地址. IP地址. 十六进制颜色. 日期. 微信号.车牌号.中文正则等.表单验证处理必备,赶紧收藏吧! 还会陆续加入新的正则进来,大家多提宝贵意见! 2.1 用户名正则 2.1.1 基本用户名正则 在做用户注册时,都会用到用户名正则校验. 定义基本用户名命名规则如下: 最短4位,最长16位 {4,16} 可以包含小写大母 [a-z]

  • JavaScript事件的委托(代理)的用法示例详解

    目录 简介 示例:事件委托 写法1:事件委托 写法2:每个子元素都绑定事件 示例:新增元素 写法1:事件委托 写法2:每个子元素都绑定事件 简介 说明 本文用示例介绍JavaScript中的事件(Event)的委托(代理)的用法. 事件委托简介 事件委托,也叫事件代理,是JavaScript中绑定事件的一种常用技巧.就是将原本需要绑定在子元素的响应事件委托给父元素或更外层元素,让外层元素担当事件监听的职务. 事件代理的原理是DOM元素的事件冒泡. 事件委托的优点 1.节省内存,减少事件的绑定 原

  • JavaScript稀疏数组与孔hole示例详解

    目录 稀疏数组是什么 JavaScript数组天生就是稀疏数组 JavaScript数组稀疏特性带来的“怪异现象” slice会复制孔 forEach.every会跳过孔(不对孔调用回调函数) map不对孔调用回调函数,但是孔会保留 filter不对孔调用回调函数,但是孔会被过滤掉 join会将孔转化为一个空字符串进行拼接,与undefined一样 初始化无孔数组的方法 Array.apply(null, Array(n))的原理 稀疏数组是什么 在绝大多数JavaScript的实现中,数组是稀

  • JavaScript实现基础排序算法的示例详解

    目录 前言 正文 1.冒泡排序 2.选择排序 3.插入排序 4.快速排序 前言 文本来总结常见的排序算法,通过 JvavScript  来实现 正文 1.冒泡排序 算法思想:比较相邻两个元素的大小,如果第一个比第二个大,就交换它们.从头遍历到尾部,当一轮遍历完后,数组最后一个元素是最大的.除去最后一个元素,对剩下的元素重复执行上面的流程,每次找出剩余元素中最大的,遍历完后,数组是升序的 算法分析:总共需要进行length * (length - 1) / 2 次比较,所以时间复杂度为O(n^2)

  • JavaScript中事件委托的示例详解

    目录 事件流 事件委托 结尾 大家好,我是前端西瓜哥.今天我们来认识一下事件委托. 所谓事件委托,就是将原本应该在当前元素绑定的事件,放到它的祖先元素上,让祖先元素来委托处理. 事件流 事件流指从页面中接收事件的顺序,也可理解为事件在页面中传播的顺序. 事件流由两阶段组成: 捕获事件 冒泡事件 我们通常用 addEventListener 给元素添加事件: document.querySelector('#card')addEventListener( 'click', function (ev

随机推荐