JavaScript作用域

JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里.

—— JS权威指南

在JS里,一切皆对象,函数也是。

一、有什么用

什么时候会用到它?它的存在有什么意义?这是我在学习一个新知识的时候首先发起的疑问。那么,在JavaScript里,作用域有什么用?

作用域规定了变量和函数的可访问范围,这个可访问范围可以细分为两个场景:变量和函数的可见性和生命周期。

  • 可见性:当访问某个变量的时候,访问的是局部变量还是全局变量?重复命名了多个变量,到底访问的是哪个值?这个变量现在能不能用,为什么有时候会返回undefined?
  • 生命周期:变量是一直存在在内存中么?什么时候会被销毁?比如定义在函数内部的变量被称为局部变量,这个变量只存在函数内部,函数调用后将会被销毁,等等...当然如果有闭包什么的就要另当别论,在这里只讨论最一般的情况。

二、全局作用域 & 局部作用域

//函数一
var authorName = "jennifer"; function doSomething() { anotherName = "james"; var blogName = "smoothlily";
function innerSay() {
alert(blogName);
}
innerSay();
} console.log(authorName); //jennifer
doSomething(); //smoothlily
console.log(anotherName); //james
console.log(blogName); //脚本错误
innerSay(); //脚本错误

针对可见性这个问题,可以聊一聊JS中规定的两个作用域:全局作用域,局部作用域。

  • 全局作用域(Global Scope)

    在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:

最外层函数和在最外层函数外面定义的变量拥有全局作用域:

如函数一的变量authorName。

所有未定义直接赋值的变量自动声明为拥有全局作用域:

如函数一的anotherName。

这种情况在写代码时最好不要出现,想要拥有全局作用域的变量还是乖乖的在脚本最开始显性声明全局变量。

所有window对象的属性拥有全局作用域,例如window.name、window.location、window.top等等

  • 局部作用域(Local Scope)

和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,最常见的就是函数内部:如函数一的blogName。

三、作用域链(Scope Chain)

在说作用域链的时候,要分为两个“时间点”:函数创建时以及函数执行时

这里借用梦想天空做的两个图:

函数创建时:

function add(num1,num2) {
var sum = num1 + num2;
return sum;
}

函数在创建时,会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性,使其包含创建函数的那个时刻下,作用域中对象的集合,也就是函数的作用域链,这个作用域链直接决定哪些数据被函数访问。

函数执行时:

var total = add(5, 10)

函数执行时,创建一个活动对象,活动对象在一开始的时候,只包含arguments对象。

当遇到变量声明时:

var a = 10;

会将这个变量复制到活动对象中。

当遇到变量访问时,会沿着作用域链做标识符解析(后续会提到),直至找到这个变量。

活动对象包含了函数的所有局部变量、命名参数、参数集合以及this,这些值按照它们出现在函数中的顺序被复制到活动对象中。然后此对象会被推入作用域链的前端,当运行期上下文被销毁,活动对象也随之销毁。

标识符解析

作用域链的用途,是为了保证对执行环境有权访问的对象的有序访问。标识符解析沿着作用域链一级一级地搜索标识符。搜索过程始终从作用域链的最前端开始(活动对象),逐级向后访问(直到全局对象),直至找到标识符为止,如果找不到,则会报错。

其他书单

JavaScript框架设计-司徒正妹

大放异彩的伪元素——可以做什么?

当我们谈论颜色时,我们在谈论什么 - 基础知识篇

参考文献

JavaScript 开发进阶:理解 JavaScript 作用域和作用域链

Javascript作用域原理

[JavaScript] JavaScript作用域深度解析的更多相关文章

  1. Javascript的作用域和闭包(一)

    一.作用域是什么? 几乎所有的编程语言最基本的功能之一,就是能够存储变量的值,并且能访问和修改这些值. 修改变量值的过程我们通常在程序执行时,称为改变一个对象的状态.有了状态,让程序变得有非常有趣. ...

  2. [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析

    [WebKit内核] JavaScript引擎深度解析--基础篇(一)字节码生成及语法树的构建详情分析 标签: webkit内核JavaScriptCore 2015-03-26 23:26 2285 ...

  3. 深度解析javascript中的浅复制和深复制

    原文:深度解析javascript中的浅复制和深复制 在谈javascript的浅复制和深复制之前,我们有必要在来讨论下js的数据类型.我们都知道有Number,Boolean,String,Null ...

  4. 42套JavaScript深度解析教学视频!合集

    本文首发于:风云社区SCOEE(社区旨在普惠软件.图片.音乐.视频.素材.文档等互联网资源.为大众提供多样化的服务,以及主要涵盖学术科学.电脑技术.文化人文.体育健身等领域的知识和信息,获得用户的支持 ...

  5. 深度解析javaScript常见数据类型检查校验

    前言 在JavaScript中,数据类型分为两大类,一种是基础数据类型,另一种则是复杂数据类型,又叫引用数据类型 基础数据类型:数字Number 字符串String 布尔Boolean Null Un ...

  6. JavaScript从作用域到闭包

    目录 作用域 全局作用域和局部作用域 块作用域与函数作用域 作用域中的声明提前 作用域链 函数声明与赋值 声明式函数.赋值式函数与匿名函数 代码块 自执行函数 闭包  作用域(scope) 全局作用域 ...

  7. JavaScript中---作用域

    作用域: 变量还有函数作用的范围. 浏览器的内核主要有两大功能,一个是渲染页面,另一个就是我们的JavaScript的解释器了. 我们主要来说说JavaScript解释器,在解析时是怎么样的工作原理. ...

  8. 浅谈JavaScript的作用域

    前段时间学了下JavaScript作用域,这个东西在JavaScript非常重要,也是JavaScript很基础的东西,正如少林里面基础武功,有了基础,才能学绝世武功. 作用域的作用是啥?一套设计良好 ...

  9. JavaScript的作用域与作用域链

    作用域 作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期.可以说,变量和函数在什么时候可以用,什么时候被摧毁,这都与作用域有关. JavaScript中,变量的作用域有全局 ...

随机推荐

  1. [置顶] 自己写代码生成器之生成Dal层代码(获取数据库所有表名称)

    自己写代码生成器之生成Dal层代码(获取数据库所有表名称) --得到数据库birthday所有表名称 select name from sysobjects where [type]='U' --se ...

  2. 修改mysql数据存储的地址

    修改mysql数据存储的地址 修改步骤如下 1,修改前为默认路径/var/lib/mysql/,计划修改为/data/mysql/data mysql> show variables like ...

  3. Java多线程编程(二)

    在 Java多线程编程(一) 中的多线程并没有返回值,本文将介绍带返回值的多线程. 要想有返回值,则需要实现新的接口Callable而不再是Runnable接口,实现的方法也改为call()方法,执行 ...

  4. 斐波那契数列 51nod

    1242 斐波那契数列的第N项 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 斐波那契数列的定义如下:   F(0) = 0 F(1) = 1 F(n) ...

  5. Ubuntu上安装QQ2015

    先不卖关子直接上图:Ubuntu 14.04.5 LTS Deb包下载地址: http://www.longene.org/download/WineQQ7.8-20151109-Longene.de ...

  6. android改动tab 导航 指示器颜色

    我事实上想改动的上面的蓝色条条,改成红色. 这个问题实在是困扰我了太长时间.之前參照google的这个文章: https://developer.android.com/training/basics ...

  7. linux下mysql5.5的安装

    #rpm –qa|grep –i mysql查看已安装的mysql版本 如果有已存在的mysql版本则删除 安装服务端和客户端,去Oracle官网下载: # rpm -ivh MySQL-serve ...

  8. HDU 5144 NPY and shot(三分法)

    当时做这道题时一直想退出物理公式来,但是后来推到导数那一部分,由于数学不好,没有推出来那个关于Θ的最值,后来直接暴力了,很明显超时了,忘了三分法的应用,这道题又是典型的三分求最值,是个单峰曲线,下面是 ...

  9. C#操作Excel(NPOI)

    这两天需要读取Excel文件,网上找了找,发现NPOI用的是最多的,于是研究了一下.这里大概介绍一下. 首先,在NPOI中一个Excel文件对应了一个IWorkbook对象,Excel中的一个工作表对 ...

  10. VS2010 快捷键--我的总结

    启动VS,可在运行中输入“devenv”: [窗口快捷键] Ctrl+Alt+L 解决方案管理器 Ctrl+W,C: 类视图      Ctrl+W,O: 输出视图      Ctrl+W,T: 任务 ...