`
shuxiang
  • 浏览: 26868 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

JS读书笔记(四)变量作用域

阅读更多

未定义的变量

未声明的变量

未赋值的变量

 

未定义的变量 = 未声明的变量

 

  • 尝试读取未声明的变量会引起运行时错误。
  • 尝试给未声明的变量赋值不会引起错误,相反,程序会在全局作用域中隐式地声明它。
  • 尝试读取未赋值的变量,将会得到一个默认值,即undefined。

变量作用域的基本规:

  • 在域中以var声明的变量只在当前域或者当前域的子域起作用。
  • 对变量的查找总是从当前域开始,递归向上查找各级嵌套父域,最后到达全局。因此如果给一个当前域的局部变量与父域中的局部变量或者全局变量起相同的的名字,就能有效地隐藏上级变量或全局变量。
  • javascript除函数外的任何程序段落都不是独立的域。换句话说javascript没有块级作用域
    for(var i = 10;i < 10;i++)
      {
         do something
      }
    
    alert(i);// i = 9
     

javascript变量作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,编译器通过静态分析就能确定,因此词法作用域也叫静态作用域。

 

javascript在执行每个函数实例时,都会创建一个执行环境,执行环境里包括一个调用对象,调用对象是一个scriptObject,用于保存内部变量表,内嵌函数表,父级引用表等语法分析结构 (注意内部变量表和内嵌函数表等信息是在语法分析阶段就已经得到,并保存在语法树中。函数实例执行时,会将这些信息从语法树复制到scriptObject上)。

 

var arg = 1;
function funcTest() {
    alert(arg);
    var arg = 2;
}
arg = 10;
funcTest();

 

 该函数的输出是undefined而不是10,因为在funcTest函数执行时,进入funcTest对应的作用域,在执行到alert时遇到了变量名arg,则会在当前作用域中查找,由于arg = 2被定义在alert方法,所以在开始编译的时候,(词法分析已经获得定义的变量和方法,这也正说明了:变量作用域是在定义时决定而不是执行时决定,也就是说词法作用域取决于源码,编译器通过静态分析就能确定 )这当前作用域中存在变量arg,但并没有赋值,故arg的值为undefined。

 

说的很好的一篇关于作用域的文章

 

另一篇文章里对作用域的说明:

 

JavaScript中的函数是基于静态作用域(也叫词法lexical作用域),而不是动态作用域。这句话的意思是JavaScript中的函数运行在它们被定义的作用域里 ,而不是它们被执行的作用域里 。在一个静态作用域里,变量永远指向它的最顶层作用域 。这是程序文本(program text)的一个属性并且与运行时调用的堆栈无关。因为匹配变量的作用域仅仅只需要分析程序文本即可,这样的作用域我们叫作静态作用域(lexical scoping)

function f1() {
   var a = 20;
   return function () { alert(a); }
}

var b = f1();
b();

结果:20

 

function f1() {
    var a = 20;
    return f2
}

function f2() {
   alert(a);
}

var b = f1();
b();

 结果:undefined ( 其实是报错的,因为引用了未定义的变量)

 

在程序1里一个匿名函数b() 被声明时,变量a 已经被保存在作用域里。所以得到20.但是在程序2里在函数f2() 里,没有声明变量a 所以没有任何值。

一但函数被定义,它会“记住”它的作用域与作用域链。这也并不是意味着函数里的所有变量都是这样。正好相反,你可以任意的添加、修改和删除。函数里都会保存最新的变量。但是必须知道变量是什么时候被定义而并不是这个作用域里它什么时候包含的。

 

静态作用域的几个特点

  • 在程序里特殊地方定义的变量永远指向具有相同定义的变量,即程序每次执行时被执行函数所在的作用域里相同定义的变量 (这句话没咋明白)
  • 变量是可以通过静态检查(static examination)源码中的作用域里出现的标识符(var)来将其值(value)改变的,而不是把整个函数做为一个整体来执行。

 

 

分享到:
评论

相关推荐

    javascript权威指南 学习笔记之变量作用域分享

    //声明,并且赋值,即定义了 下面是几点总结: 变量的作用域:全局的和局部的。(注意:如果尝试读取一个未声明的变量的值,javascript会生成一个错误) 第一点:在都使用var关键字修饰变量的情况下,如果给一个局部...

    JavaScript 学习笔记之变量及其作用域

    使用var 定义变量:定义该变量的作用域的局部变量,这种定义变量的方法也被成为显式声明。 这么说不理解的话可以看看下面这个简单粗暴的例子: 代码如下: test(); function test(){ var firstDemo=”hello”;//定义...

    不同浏览器javascript变量作用域的处理方法

    关于变量作用域,和IE,firefox对js的不同处理,这里有几个例子,有几个是原来从别处看到的记的笔记,有的是我自己挖掘出来的. 2.1 [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]2.2  [Ctrl+A 全选 注:如需引入...

    js基础教学笔记.docx

    js入门的相关知识点,b站教学视频做...12、 JavaScript作用域 16 13、 JavaScript预解析 16 14、 JavaScript对象 17 15、 JavaScript内置对象(MDN 查文档) 19 16、 JavaScript简单类型与复杂类型 25 17、 掌握知识 27

    深入理解ES6学习笔记之块级作用域绑定

    众所周知,js中的var声明存在变量提升机制,因此ESMAScript 6引用了块级作用域来强化对变量生命周期的控制 let const 声明不会被提升,有几个需要注意的点 1、不能被重复声明 假设作用域中已经存在某个标识符(无论...

    浅析JavaScript中的变量复制、参数传递和作用域链

    今天在看书的过程中,又发现了自己目前对Javascript存在的一个知识模糊点:JS的作用域链,所以就通过查资料看书对作用域链相关的内容进行了学习。今天学习笔记主要有这样几个关键字:变量、参数传递、执行环境、变量...

    Javascript学习笔记二 之 变量

    一.关于Javascript变量声明 在Javascript中,声明一个变量 var a=1; 也可以直接 a=1; 这两种表达是有区别的, 一个是当前作用域的局部变量,另一个则是当前作用域的全局变量;... // error 二.Javascript变量作用域

    Javascript学习笔记3 作用域

    在Javascript,全局环境本身就一个对象。... 言归正传,当我们写下:var i=1时,其实就是声明了一个window作用域的一个变量。 而当我们写下i=1时,是声明了一个window的属性。 看这样一段代码: [Ctrl+A 全选 注:

    谈谈我对JavaScript原型和闭包系列理解(随手笔记9)

    变量作用域完成对信息的隐蔽,也就是处理“割据”问题。 js中是没有块级作用域的(ES6中有一个let,可以在{},if,for里面声明,同时作用域限定在块级。let声明的变量不存在变量提升!这里不谈论这个,因为我也是...

    Javascript学习笔记之函数篇(六) : 作用域与命名空间

    在之前的介绍中,我们已经知道 Javascript 没有块级作用,只有函数...每一次引用一个变量时,Javascript 会往上遍历整个全局作用域直到找到该变量。如果遍历完整个全局作用域仍然没有找到该变量,则抛出一个 Reference

    javascript学习笔记(十三) js闭包介绍(转)

    一、变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。 代码如下: var n=999;...

    JavaScript.The.Good.Parts阅读笔记(二)作用域闭包减缓全局空间污染

    如代码块 代码如下: if (true...由于缺少块级作用域,最好在函数体的顶部声明函数中可能用到的所有变量。 闭包特性: 虽然缺少块级作用域,但是函数的作用域还是存在的。 这种作用域有一个好处,就是内部函数可以访问定

    JS页面获取 session 值,作用域和闭包学习笔记

    本文实例讲述了JS页面获取 session 值,作用域和闭包。分享给大家供大家参考,具体如下: Javascript获取session的值: var name= "${sessioScope.变量名}"; 注意这里面需要使用 “” 把 El 表达式给括起来,否则...

    javascript从入门到跑路—–小文的js学习笔记(7)——–js函数

    含义: 一般来说一段程序代码中使用的变量和函数并不总是可用的,限定其可用性的范围即作用域,作用域的使用可以提高程序逻辑的局部性,增强程序的可靠性,减少名字冲突。 分类: 全局作用域: 在当前文件中的所有...

    JavaScript 中级笔记 第三章

    基于浏览器的JavaScript语言有一门有趣的特性是,所有属于全局作用域的变量都是window对象的属性。 看下面代码: [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行] 我们再上例的基础上,再添加一个函数来修改

    javascript作用域链(Scope Chain)用法实例解析

    本文实例分析了javascript作用域链(Scope Chain)用法。分享给大家供大家参考,具体如下: 关于js的作用域链,早有耳闻,也曾看过几篇介绍性的博文,但一直都理解的模棱两可。近日又精心翻看了一下《悟透Javascript》...

    面向对象javascript笔记

    面向对象的 javascript 学习 大家好,根据我的学习...引用,函数重载和类型检查,作用域,图解prototype和constructor, 闭包,上下文,公共方法和私有方法,公共变量私有变量,特权方法,静态方法,命名空间,编码建议

    javascript入门笔记

    Javascript,简称为 JS,是一款能够运行在 JS解释器/引擎 中的脚本语言 JS解释器/引擎 是JS的运行环境: 1、独立安装的JS解释器 - NodeJS 2、嵌入在浏览器中的JS解释器 JS的发展史: 1、1992年 Nombas 开发...

Global site tag (gtag.js) - Google Analytics