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. 获取git的当前分支名称

    git branch | grep \"*\" | awk -F \"_\" '{print $2}'

  2. otl获得sql出错位置(oracle)

    项目的一个需要,要获得sql出错的位置,从而给出类似sqlplus的错误提示(如下) sql出错原因易获得,记录在otl_exception::msg,但出错位置就不是那么容易了. 默认情况下otl异 ...

  3. MD5方法代码(生成小写的md5) C#版本

    public string GetMD5Str(string input) { // Use input string to calculate MD5 hash MD5 md5 = System.S ...

  4. JS 实现显示和隐藏div(以百度地图为例)

    主要参考的文章:https://my.oschina.net/xsh1208/blog/215811,https://zhidao.baidu.com/question/568774688.html ...

  5. ubuntu12.04管理员账户登录不了桌面,只能客人会话登录

    ubuntu12.04管理员账户登录不了桌面,只能客人会话登录 求助!!ubuntu12.04管理员账户登录不了桌面,只能客人会话登录. 登录管理员账户时,输入密码后,一直在登录界面循环 费了好大劲啊 ...

  6. Cloudra公司CCP:DS——认证数据专家

    原文:http://vision.cloudera.com/24195/. 译文: 每天我都能看到大数据怎样改变我们生活的文章.数据科学家们正在生物医药领域找寻新的方法治愈癌症.帮助银行与欺诈做斗争, ...

  7. Linux命令之查找

    在Linux中,有非常多方法能够做到这一点.国外站点LinuxHaxor总结了五条命令,你能够看看自己知道几条.大多数程序猿,可能常常使用当中的2到3条,对这5条命令都非常熟悉的人应该是不多的. 1. ...

  8. CXF WebService整合Spring

    转自http://www.cnblogs.com/hoojo/archive/2011/03/30/1999563.html 首先,CXF和spring整合需要准备如下jar包文件: 这边我是用Spr ...

  9. apktool的下载地址

    googlecode将要关闭,代码转移到以下网址 http://ibotpeaches.github.io/Apktool/

  10. Java基础知识强化之集合框架笔记01:集合的由来与数组的区别

    1. 集合的由来: 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储.而要想存储多个对象,就不能是一个基本的变量,而应该 ...