认识Javascript中的作用域和作用域链
作用域
只要写过java或者c#等语言的同学来说,相信一定能理解作用域的概念,在作用域的范围中,我们可以使用这个作用域的变量,对这个变量进行各种操作。可是,当使用Javascript的时候,相信很多的同学都会遇到迷惑的时候。
例如,我们看一个常用并经典的案例。
var name = '张三'; function fun() {
console.log(name);
var name = '李四';
}
fun()
对于初识javascript的同学来说可能会认为打印的是“张三”,不过我们惊奇的发现打印的是“undefined”,下面我们来分析分析为什么会出现这样的情况。
首先,我们需要认识三个概念:全局变量、局部变量以及变量提升
全局变量
在全局定义的变量为全局变量,在这个作用环境中的所有函数对象都是可以调用到全部变量。
局部变量
顾名思义,局部变量即定义在函数内部的变量。他的作用环境局限在变量所在的局部环境中。
变量提升
在javascript中,函数和变量声明都会被提升到函数的顶部。通俗的来说就是我们可以先使用变量,然后再声明函数。
接下来,我们看看下面几个例子:
例1:
var name = "张三"
function fun() {
console.log(name);
}
fun()
显而易见,这次我们的打印结果是 “张三”。
现在我们看第二个例子:
例2:
var name = "张三"
function fun() {
console.log(name);
}
fun()
这次的结果同样是显而易见的,打印了 “张三”。
上面两个例子我们认识了全局变量和局部变量,现在我们再看看第三个例子。
例3:
function fun() {
console.log(name)
var name = "李四";
console.log(name);
}
fun()
这里就需要我们用到变量提升的概念,上面我们提到,javascript对函数和变量声明提升到函数头部,所以在执行第一次打印之前,name这个变量已经被环境帮我们声明了,但是环境并不会帮我们赋值,所以,第一次会打印undefined,然后,第二次打印“李四”。
上面的程序我们换一种写法或许更好理解。
function fun() {
var name = undefined;
console.log(name)
name = "李四";
console.log(name);
}
fun()
现在我们就可以来理解下最开始说的这个例子了。
var name = '张三'; function fun() {
console.log(name);
var name = '李四';
}
fun()
1. 在全部环境中定义了全局变量 name="张三";
2. 在局部环境中定义了name=“李四”,所以局部变量和全局变量名字相同的时候,会优先获取局部变量的值;
3. 由于我们打印name变量是在定义name之前,所以,根据变量提升的特性,所以这里我们会打印 undefined。
相信通过前面几个例子,我们对作用域已经有了一些了解,下面就对作用域进行一下总结。
概念:作用域是一种规则,是 javascript中所有可访问的变量的集合(函数,对象都是变量)。
作用:我们通过作用域可以访问权限内的所有变量,并进行相应操作。
作用域链
对于理解了javascript中的作用域之后,作用域链就是一个比较容易理解的概念。同样,我们也通过一个例子来看。
var age = 18; function a() {
var sex = 'sex'; b();
function b() {
var color = 'green'; console.log({age, sex, color})
}
} a();
相信大家都能一样看出这段程序的输出结果是{age: 18, sex: "sex", color: "green"},虽然程序简单,不过却是我们理解作用域链的一个好例子。
我们再输出的时候会打印age,sex,color三个变量。
对于color变量来说,本来就在当前执行函数b的作用域内,所以color变量的寻找路径是b.color;
对于sex变量来说,在执行函数b的作用域中找不到sex变量,所以,他会沿着b函数的作用域链找到函数a的作用域,所以sex变量的寻找路径是 b > a.sex;
对于age变量来说,执行函数b中找不到,沿着作用域链找到a函数的作用域依然没找到,就会一直沿着作用域链找到window环境,在这里找到了变量age,所以age变量的寻找路径是b>a>window.age
通过上一个例子,我们应该可以清楚的认识作用域链是什么样的存在,同样我们也总结一下。
概念:作用域链是作用域的具体实现,通过作用域链可以确定变量被访问的权限。
作用:可以通过作用域链,了解我们在当前执行环境可以访问哪些变量。
浅陋见识,不足之处,请大神指正。
认识Javascript中的作用域和作用域链的更多相关文章
- 深入理解javascript中执行环境(作用域)与作用域链
深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...
- JavaScript中的原型、原型链、原型模式
今天,咱来聊聊JavaScript中的原型跟原型链 原型跟原型模式 这一块的知识,主要是设计模式方面的. 首先,我们知道JavaScript是面向对象的.既然是面向对象,那它自然也有相应的类跟对象等概 ...
- JavaScript 中的闭包和作用域链(读书笔记)
要想理解闭包,应当先理解JavaScript的作用域和作用域链. JavaScript有一个特性被称之为“声明提前(hoisting)”,即JavaScript函数里声明的所有变量(但不涉及赋值)都被 ...
- JavaScript中的闭包和作用域链
这部分几乎是JavaScript中最难的部分,也是面试官最爱问的地方. 下面的内容是我以前写的<JavaScript学习手册>中被客户删除的部分,理由听起来有点诡异:太难.
- Javascript中没有块级作用域(模仿)
在C/C++中,由花括号封闭的代码块都有自己的作用域,也就是块级作用域(私有作用域).而在javascript中则没有块级作用域,首先来看一段代码: function test(){ for(var ...
- javascript中执行环境和作用域(js高程)
执行环境(execution context,为简单起见,有时也成为“环境”)是javascript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境 ...
- 一篇文章带你了解JavaScript中的变量,作用域和内存问题
1 在JavaScript中的变量分别区分为两种: 一种为基本类型值,一种为应用类型值. 基本类型值指的是简单的数据段 引用类型值为可能由多个值组成的对象 引用类型的值是保存在内存中的对象,JavaS ...
- javascript中模仿块级作用域
学过 javascript 的都知道 javascript 里面没有块级作用域的概念,这就意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,看下面的例子: function outPu ...
- JavaScript中的继承(原型链)
一.原型链 ECMAScript中将原型链作为实现继承的主要方法,基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法. 实例1: function SupType() { this.pro ...
- JavaScript中的继承与原型链
先看一个例子 function User(){} var u1 = new User(); console.log(u1.prototype);// undefined 使用对象实例无法访问到prot ...
随机推荐
- Python操作图像
安装Pillow pip install Pillow 打开图像 from PIL import Image img = Image.open("./lena.tiff") 保存图 ...
- TTL电平,CMOS电平,232/485电平,OC门,OD门基础知识
1.RS232电平 或者说串口电平,有的甚至说计算机电平,所有的这些说法,指得都是计算机9针串口 (RS232)的电平,采用负逻辑, -15v ~ -3v 代表1 +3v ~ +15v 代表0 2. ...
- Java 8 有多牛逼?打破一切你对接口的认知!
前段时间面试了一个 39 岁的程序员,结果不是很理想,没看过的点击这里阅读. 最近也面试一些 Java 程序员,不乏工作 4.5 年经验的,当我问他一些 Java 8 的新特性时,大多却答不上来. 比 ...
- 【博弈论】CF 1215D Ticket Game
题目大意 洛谷链接 给出一个长度为\(n\)的由数字组成的字符串(\(n\)是偶数).但可能有偶数个位上的数字为?. 现在有两个人\(A\)和\(B\),在?的位置上填\(0\)~\(9\)的数,一直 ...
- C++ 设置软件激活不息屏
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
- QJsonObject 遍历
遍历QjsonObject方式 方式一 QJsonObject::const_iterator it = l_obj.constBegin(); QJsonObject::const_iterator ...
- java开发环境配置,看这一篇就足够了!
可能平时大家对于安装环境的需求不是那么强烈,但是当你换了一台新电脑时,你就会发现怎么也得花费你几个小时乃至半天一天的时间.故此整理此篇文章,给有需要的小伙伴 注:本文皆win10环境 (1).JDK的 ...
- 如何在windows Server 2008虚拟机上安装SQLServer2008数据库
一.环境准备 1.cn_windows_server_2008_r2_standard_enterprise_datacenter_web_x64_dvd_x15-50360.iso 2.NDP452 ...
- 面试官:说说CountDownLatch,CyclicBarrier,Semaphore的原理?
CountDownLatch CountDownLatch适用于在多线程的场景需要等待所有子线程全部执行完毕之后再做操作的场景. 举个例子,早上部门开会,有人在上厕所,这时候需要等待所有人从厕所回来之 ...
- Vue中封装axios组件实例
首先要创建一个网络模块network文件夹 里面要写封装好的几个组件 在config.js里面这样写 在index.js要这样写 core.js文件里面内容如下 然后要在main.js文件里面要设置 ...