转:javascript变量的作用域

原文请访问http://www.cnblogs.com/rubylouvre/archive/2009/08/21/1551270.html,

我也只是为了做个记录

javascript变量的作用域

<script type="text/javascript">  
var a=100;  
var b=true;  
function test(){  
    alert(a);  
    alert(b);  
    b=false;  
    alert(b);  
    var a=200;  
    alert(a/2);  
    alert(++Math.PI);  
    alert(Math.PI++);  
}  
test();
</script>

为什么第一个alert为undefined,而第二个为true。这问题也可以延伸为——alert(b)时怎么就会找外部的b,而alert(a)时就不会往外面找?!

我们都明白局部变量的优先级大于全局变量,或者说内围作用域的变量的优先级比外围的高。当JS引擎在当前作用域找不到此变量时,它就往外围的作用域找。不过, 在这之前,有一个严肃的问题是,究竟当前作用域存不存在这个变量。像javascript这样的解释型语言,基本分为两个阶段,编译期(下面为符合大多数语言的称呼习惯,改叫预编译)与运行期。在预编译阶段,它是用函数来划分作用域,然后逐层为其以 var 声明的变量(下略称为var变量)与函数定义开辟内存空间,再然后对var变量进行特殊处理,统统赋初始值为undefined,如下图:

由上图,我们便可以推知,当前网页拥有两个a,一个b,一个test函数。如果在运行期用到除此以外的东东,如c函数或d变量啦,就会报未定义错误(用eval等非正常手段生成变量与函数的情况除外),此外,它们最多出现未赋值警告。

javascript的运行期是在为var变量与函数定义分配空间后立即执行,并且是逐行往下执行的。

  • 第1行它为外围作用域的a赋值为100
  • 第2行它为外围作用域的b赋值为true
  • 第3行进行test的作用域,我们简称为内围作用域。
  • 第4行就立即调用内围作用域的a,这时它还没有来得及赋值呢!不过它已经声明过了,因此默认为其赋值为undefined(在预编译阶段,见图),于是alert为undefined
  • 第5行就调用b时,JS引擎就拿起我画的图看了(笑),发现test的作用域内没有b,眼睛往外望,发现b了,而b在第二行就赋值为true,于是alert为true。
  • 第6行为一个赋值操作,把外围的b变量改赋为false。于是到第7行时,alert为false。以下说法不说了。

作为对比,我们改写一下例子:

这时在test函数的作用域内,b也被声明了。

掌握预编译为var变量与函数定义分配空间这一事实后,许多问题就迎刃而解。我们看犀牛书上的一个例子。

var scope = "global"
function f() { 
    alert(scope);             
    var scope = "local";      
    alert(scope);             
f();

答案呼之欲出!

我们来看更复杂的例子。

Object.prototype.test = ‘wrong‘;
var test = ‘right‘;
(function f() {
    alert(test);
})();

时间: 2024-11-01 10:58:45

转:javascript变量的作用域的相关文章

PHP (20140510)深入浅出 JavaScript 变量、作用域和内存 v 0.5

深入浅出 JavaScript 变量.作用域和内存 v 0.5 本文主要从原理入手分享变量和作用域的相关知识,最后结合本文所分享知识,再次深入了解下闭包的运行原理. 主要参考<JS高级程序设计> <JS权威指南> <高性能 JS> 三本书. 目录 1 变量 1.1 变量的声明 1.2 变量类型的特点 2 执行环境和作用域 3 再谈谈闭包 变量 对 JavaScript 稍微有点了解的同学都知道,JavaScript 中的变量与其他语言的变量有很大区别. JS 的弱类型的

关于“javascript变量的作用域”的理解

*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* BLOCKS =============================================================================*/ p, blockquote, ul, ol, dl, table, pre { margin: 15px 0; } /* HEAD

【Python全栈-JavaScript】JavaScript变量的作用域

JavaScript变量的作用域全局变量 1.当在script中定义变量,在当前script中的定义前调用是undefined,没有定义该变量时调用报错.原因是在内存中开辟了该变量的存储位置,(当执行script时将所有定义的变量名先存到栈中) 当代码解释到该语句时才会将值存在栈中,没有执行之前调用该变量就是undefined,如果没有定义就不会在内存中开辟存储位置,因此就会报错. 2.如果在上一个script中调用下面的script的变量时,这时候不但没有值,而且没有开辟存储空间.因此,在上一

JavaScript 变量、作用域和内存问题

按照ECMA-262第三版的定义,JavaScript的变量与其他语言的变量有很大区别.JavaScript变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型的规则,变量的值及其数据类型可以在脚本的生命周期内改变.尽管从某种角度看,这可能是一个既有趣又强大,同时又容易出问题的特性,但JavaScript变量实际的复杂程度还远不止如此. 1,基本类型和引用类型的值 ECMAScript变量可能包含两种不同类型的值:基本类型值和引用类

JavaScript变量、作用域和内存问题(一)

接下来博客的内容 理解基本类型和引用类型的值 理解执行环境 理解垃圾收集 按照 ECMA-262 的定义,JavaScript 的变量与其他语言的变量有很大区别.JavaScript 变量松散类型的本质,决定了它只是在特定时间用于保存特定值的一个名字而已.由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变.尽管从某种角度看,这可能是一个既有趣又强大,同时又容易出问题的特性,但 JavaScript 变量实际的复杂程度还远不止如此. 基本类型和引用

[从jQuery看JavaScript]-变量与作用域链

jQuery片段: [javascript] view plaincopy var // Will speed up references to window, and allows munging its name. window = this, // Will speed up references to undefined, and allows munging its name. undefined, // Map over jQuery in case of overwrite _jQ

深入浅出 JavaScript 变量、作用域和内存 v 0.5

本文主要从原理入手分享变量和作用域的相关知识,最后结合本文所分享知识,再次深入了解下闭包的运行原理. 主要参考<JS高级程序设计> <JS权威指南> <高性能 JS> 三本书. 目录 1 变量 1.1 变量的声明 1.2 变量类型的特点 2 执行环境和作用域 3 再谈谈闭包 变量 对 JavaScript 稍微有点了解的同学都知道,JavaScript 中的变量与其他语言的变量有很大区别. JS 的弱类型的特性决定了变量只是在特定时间(生命周期,作用域中)用于保存特定值

[label][JavaScript][The Defined Guide of JavaScript] 变量的作用域

变量的作用域 一个变量的作用域(scope)是程序中定义这个变量的区域. 全局(global)变量的作用域(scope)是全局性的,即在JavaScript代码中,它处处都有定义.    而在函数之内声明的变量,就只在函数体内部有定义,它们是局部(local)变量,作用域是局部性的.    函数的参数也是局部变量,它们只在函数体内部有定义.    在函数体内部,局部变量的优先级比同名的局部变量高.        如果给一个局部变量或函数的参数声明的名字与某个全局变量的名字相同,那么就有效地隐藏了

JavaScript变量、作用域和内存问题总结

㈠理解基本类型和引用类型的值  ⑴JavaScript变量可以用来保存两种类型的值:基本类型值和引用类型值. ⑵基本类型的值源自以下 5 种基本数据类型:Undefined.Null.Boolean.Number 和 String. ⑶基本类型值和引用类型值具 有以下特点: ? 基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中: ? 从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本: ? 引用类型的值是对象,保存在堆内存中: ? 包含引用类型值的变量实际上包含的并不是对象