理解好javascript的变量作用域和链式调用机制对用好变量起着关键的作用,下面我来谈谈这两个概念的理解。
(1)链式调用机制
作用域链的定义:函数在调用参数时会从函数内部到函数外部逐个”搜索“参数,一直找到参数为止,如果没有声明就返回null,声明了没有赋值就返回undefined,就像沿着一条链子一样去搜索,这就是作用域的链式调用。
javascrip的变量作用域跟python或者其他后端语言不同,变量一经声明,它的作用域就是全局的。在函数内部如果调用一个变量,就会发生上述的作用域链式调用的过程。
例子:
window.onload = function(){
var foo = true;
if(1==1){
var bar = foo*2;
console.log(bar);
}
console.log(foo);
}
打印的结果是:
2
true
这段代码的实现过程大体是这样的:
首先在if语句外部声明一个foo变量并给它定义赋值,在if语句内部找不到foo,就会到全局作用域去寻找foo变量。而if语句内部并没有改变foo的值,所以在外部打印foo时,它的值还是true。
 
如果像下面一样稍微修改一下代码
window.onload = function(){
var foo = true;
if(1==1){
var foo = 2;
bar = foo*2;
console.log(foo);
console.log(bar);
}
console.log(foo);
}
打印结果是:
2
4
2
if语句内部声明的变量foo把在if语句外面声明的变量foo覆盖了。
所以在声明和引用变量的时候需要格外谨慎,一不小心,变量的值就改变了。
 
在ES6之前,要防止变量被污染,要使用闭包这个概念。
ES6为了解决这个问题,提出了两种声明变量的方法
let关键字和const关键字
1)let关键字
可以将变量绑定到所在的作用域中,通常是{ ... }内部。
例如:
window.onload = function(){
var foo = true;
if (1==1){
let foo = 2;
var bar = foo*2;
console.log(bar);
}
console.log(foo)
}
打印的结果是:
4
true
显然,if语句内部声明的foo并没有影响到外部的foo,在if语句外部调用foo,还是原来的值true。
2)const关键字
const关键字同样是用来创建块作用域变量的,但其值时固定不变的。
 
(2)js中的特殊情况:作用域链的改变
以下语句或方法都会产生作用域链的改变
1)with(实参){ } 语句
2)try{ } catch(err){ } 语句
2)eval()方法
函数调用参数时都不会先执行函数内部的参数,而是调用此前已经定义过的参数,及函数被传递进来的实参。如果没用实参的相关属性值没有定义过,再调用函数内部的参数属性,即所谓的临时改变。(catch内部的err比较特殊,有优先调用的权力)
 
(3)块作用域的理解
块作用域的定义:函数内部的参数只能在函数/语句内部使用,函数/语句块外部不能使用,很多情况下块作用域是隐式的,即表面上看不出来。
跟全局变量不同,块作用域内的变量不会链式调用。
块作用域举例:
1)for(var i)循环内部定义的参数i。在for循环结束后就会被销毁
2)try{ } catch(err){ }语句内部的err对象。err只在catch内部调用,一旦函数执行完毕,马上销毁,即使函数外部想调用或者重新定义err也是无法调用到catch内部的err的
3)with(var i)内部新定义的参数i
 

对JS作用域和作用域链的理解的更多相关文章

  1. js原型和原型链个人理解(我的理解)

    <script> //普通对象与函数对象,js万物皆是对象 //自带的 function a1() { function f1() {} var f2=function () {} var ...

  2. JS原型、原型链深入理解

    原型是JavaScript中一个比较难理解的概念,原型相关的属性也比较多,对象有”prototype”属性,函数对象有”prototype”属性,原型对象有”constructor”属性. 一.初识原 ...

  3. JavaScript筑基篇(三)->JS原型和原型链的理解

    删除理由:很久以前写的,当时理解不够深入,这样描述反而看起来更复杂了.因此就删掉,免得误人子弟! 可以看看另一篇文章:[如何继承Date对象?由一道题彻底弄懂JS继承.](http://www.cnb ...

  4. 关于js中的原型链的理解

    我们知道无论什么时候只要创建了一个函数,就会为该函数创建一个prototype属性,这个属性指向函数的原型对象,默认情况下所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包 ...

  5. js原型,原型链的理解

    1.所有引用类型(函数.数组.对象)都拥有_proto_属性(隐式原型) 2.所有函数拥有prototype属性(显式原型)(仅限函数) 3.原型对象:拥有prototype属性的对象,在定义函数时就 ...

  6. 理解js中的作用域,作用域链以及闭包

    作用域变量作用域的类型:全局变量和局部变量全局作用域对于最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的 <script> var outerVar = " ...

  7. js对象系列【二】深入理解js函数,详解作用域与作用域链。

    这次说一下对象具体的一个实例:函数,以及其对应的作用域与作用域链.简单的东西大家查下API就行了,这里我更多的是分享自己的理解与技巧.对于作用域和作用域链,相信绝大多数朋友看了我的分享都能基本理解,少 ...

  8. js基础梳理-如何理解作用域和作用域链?

    本文重点是要梳理执行上下文的生命周期中的建立作用域链,在此之前,先回顾下关于作用域的一些知识. 1.什么是作用域(scope)? 在<JavaScritp高级程序设计>中并没有找到确切的关 ...

  9. 了解 JS 作用域与作用域链

    (1)作用域 一个变量的作用域(scope)是程序源代码中定义的这个变量的区域. 1. 在JS中使用的是词法作用域(lexical scope) 不在任何函数内声明的变量(函数内省略var的也算全局) ...

  10. Js作用域与作用域链详解

    一直对Js的作用域有点迷糊,今天偶然读到Javascript权威指南,立马被吸引住了,写的真不错.我看的是第六版本,相当的厚,大概1000多页,Js博大精深,要熟悉精通需要大毅力大功夫. 一:函数作用 ...

随机推荐

  1. [译]ElasticSearch vs. Solr

    在Gen2产品的早期阶段, 我们事实上是失败的, 这促使我们重新审视我们现有的技术栈. 我们仔细分析系统中的每个独立的组件,并记录下来, 当然其中也包括构成我们核心功能的搜索引擎技术. 在我们的通用日 ...

  2. tcp 三次握手 四次挥手

    TCP协议中的三次握手和四次挥手 建立TCP需要三次握手才能建立,而断开连接则需要四次挥手. 三次握手,建立连接 首先Client发送连接请求报文,Server端接收连接后回复ACK报文,并为这次连接 ...

  3. Shell脚本 | 性能测试之CPU占有率

    Android 是一个基于 Linux 内核的移动操作系统,Linux 的 CPU 占有率的计算方式也可以应用到 Android App 上. 今天分享的这个脚本的功能,是在多核情况下计算进程的 CP ...

  4. Java并发编程笔记之StampedLock锁源码探究

    StampedLock是JUC并发包里面JDK1.8版本新增的一个锁,该锁提供了三种模式的读写控制,当调用获取锁的系列函数的时候,会返回一个long 型的变量,该变量被称为戳记(stamp),这个戳记 ...

  5. C语言实现多态

    C语言实现多态 首先声明,大神就不要看了.小弟水平有限. C++多态是通过虚函数表实现的,类似于JAVA多态的实现方式.关于Java多态的实现方式可以看我之前写过的一篇不是很完善的文章.从JVM角度看 ...

  6. 逆向知识之CS辅助/外挂专题.2.实现CS1.6无限夜视仪.无限闪光烟雾高爆弹.

    逆向知识之CS辅助/外挂专题.2.实现CS1.6无限夜视仪.无限闪光烟雾高爆弹. 关于人物子弹无限可以观看上一篇博客. 一丶无限夜视仪. 无限夜视仪找法. 1.CE附加游戏. 2.搜索0或者1. 3. ...

  7. Notyf - 超级简单、响应式的 JS 通知插件

    通知是网站的常用功能之一,可以用来显示消息.通告.提示等等.Notyf 是一款超级简单.响应式的 JS 通知插件,不依赖 jQuery 库,可以独立使用.赶紧试用一下吧! 在线演示      免费下载 ...

  8. CEF C++环境搭建

    第一步:下载CEF 到这里下载最新版本的CEF http://cefbuilds.com/ 下载解压之后,大概会看到如下图所示的文件 cefclient:是一个比较复杂的示例代码cefsimple:是 ...

  9. shell | {}和()

    执行 bash -n xx.sh用于检测脚本语法是否有错误 bash -x xx.sh用于追踪执行 ${var} 用于限定变量名称的范围,并且支持通配符 $(cmd) shell会先执行括号的cmd, ...

  10. [CF718C] Sasha and Array

    Description 给定一个数列,维护两种操作 操作 \(1\),将区间 \([l,r]\) 的数字统一加 \(x\). 操作 \(2\),求 \(\sum \limits_{i=l}^r f(v ...