认识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 ...
随机推荐
- 《Android逆向反编译代码注入》 - 逆向安全入门必看视频教程
适合人群: Android开发人员.逆向反编译开发人员.以及对Android逆向安全感兴趣的朋友. 视频地址: 51CTO学院:https://edu.51cto.com/course/24485 ...
- Fiddler抓包工具 请求图标为一个锁的图标的设置
第一步,Fiddler抓包的数据 前面的都是一个锁的图标,的设置方法, 然后 点击打开 按此设置图一 在图二, 图三. 其他默认就好
- PowerShell 语法
PowerShell 之 教程 PowerShell 中变量.函数命名等不区分大小写,但字符串区分大小写 powershell 脚本文件 扩展名为 .ps1 调用操作符 & + Cmd Cmd ...
- github 上传与删除项目
在github上创建好仓库后,在本地创建一个仓库 1.先要初始化本地仓库 git config --global user.name 'you name' git config --global us ...
- Git 高级用法,你会了吗?
请注意我有意跳过了 git commit.git pull/push 之类的基本命令,这份小抄的主题是 git 的一些「高级」用法. 导航 -- 跳到之前的分支 git checkout - 查看历史 ...
- JAVA Schedule的Cron表达式
spring中用到的定时任务,一般用到的有Timer()和Schedule Cron表达式一般是程序的定时任务中所要起的..我们用的springboot中的@Schedule中,启动类中添加enabl ...
- swoole执行外部程序称为进程
<?php $child = new \Swoole\Process(function(\Swoole\Process $process){ $process->exec('/usr/lo ...
- scrapy 采集数据存入excel
# -*- coding: utf-8 -*- # Define your item pipelines here # # Don't forget to add your pipeline to t ...
- 零基础了解Python的用途
在我们学习Python之前,我们肯定首先要了解Python它到底是什么,Python到底可以做什么?当然对于现在的社会来讲Python的热度毋庸置疑,现在国内,不仅考国家二级计算机证需要学习Pytho ...
- 在学习python的过程中,遇到的最大的困难是什么?
本人文科生,回顾自己近 2 年的Python 自学经历,有一些学习心得和避坑经验分享给大家,让大家在学习 Python 的过程中少走一些弯路!减少遇到不必要的学习困难! 首先,最开始最大的困难应该就是 ...