`
suyang119
  • 浏览: 16786 次
社区版块
存档分类
最新评论

Javascript作用域浅析

阅读更多
学习任何编程语言,都逃不过理解变量的作用域。

在javascript中,变量的作用域有全局(window对象)作用域和函数调用作用域。


以下变量具有全局作用域
1. 所有在最外层定义(非函数体内定义)的变量都拥有全局作用域
2. 所有末定义直接赋值的变量,系统会自动声明为拥有全局作用域的变量
3. 所有window对象的属性拥有全局作用域


以下变量具有函数作用域
1. 在函数体内部用var定义的变量,这里要注意一点,只要是在函数里定义的变量,就算是在最后一句定义,该变量也拥有整个函数的作用域。



特别应该说明的一点是,作用域是层层包含的,最外层是全局作用域,里面可以包含函数调用作用域,函数调用作用域里面还可以再有函数作用域,下面,我们看一个简单的例子:


<mce:script type="text/javascript"><!-- 
var scope = "global"; 
window.x = "x-global"; 
 
var f1 = function(){ 
    var scope = "function1"; 
    y = "y-golbal"; 
    alert(scope);    //will display function1 
    alert(window.scope);  //will display global 
    alert(x);               //will display x-global 

 
f1(); 
 
alert(scope);//will display global 
alert(y);    //will display y-golbal 
// --></mce:script> 



这个例子说明了简单的全局作用域和函数作用域的区别,我们再思考一下问题,如果函数f1里面没有变量scope,而全局作用域里面有这个变量,会有什么情况呢?



[javascript] view plaincopy
<mce:script type="text/javascript"><!-- 
var scope = "global"; 
 
var f1 = function(){ 
    //var scope = "function1"; 
    alert(scope);    //will display global 
    alert(window.scope);  //will display global 
     

 
f1(); 
 
alert(scope);//will display global 
// --></mce:script> 



为什么会这样呢,这是由于javascript的寻找变量的机制造成的。上面己经说了,作用域是层层包含的,上面的这个例子的层次应该是这样的: 全局作用域->f1的作用域。而javascript查找一个变量时,会从当前作用域往上找,直到找到为止,所以这个例子中,先在f1的作用域找scope,找不到,则到外层的全局作用域找,在全局作用域中找到了scope,就使用该变量,这个例子中,如果在全局作用域也找不到变量scope,则会报错。
下面我们把这个例子改一下,就会有一个很有趣的现象



[javascript] view plaincopy
<mce:script type="text/javascript"><!-- 
var scope = "global"; 
 
var f1 = function(){ 
     
    alert(scope);    //will display undefined 
    alert(this.scope);  //will display global 
    var scope = "function1";  //declare scope here 

 
f1(); 
 
alert(scope);//will display global 
// --></mce:script> 



这里还是用javascript查找变量的机制来解释,首先在f1的作用域里面找,而f1定义了该变量,所以使用该变量,但是还末赋值,所以是undefined。这里要说明一点,就是作用域内的变量不管在函数的哪里声明,javascript都会在函数运行前在作用域内包含该变量。
下面,我们再看复杂一些的例子:



[javascript] view plaincopy
<mce:script type="text/javascript"><!-- 
var scope = "global"; 
var scope2 = "global-scope2" 
 
var f1 = function(){ 
    var scope = "function1"; 
    var scope2 = "function1-scope2"; 
    (function(){ //function2 
        var scope = "function2"; 
        (function(){  //function3 
            alert(scope);  //will display function2 
            alert(scope2);  //will display function1-scope2 
        })(); 
         
    })(); 
     
     

 
f1(); 
// --></mce:script> 





下面,我们还是以javascript查找变量的机制来解释一下。首先,我们看看作用域的包含情况: 全局作用域-> f1的作用域 ->f2的作用域-> f3的作用域。对于变量scope,先在f3作用域内找,没找到,往外,在f2作用域里找到,使用该值,所以打出的值为 function2。对于scope2,先在f3找,没找到,住外,在f2找,还是没找到,再往外,在f1找,找到,使用该值,所以打出的值为function1-scope2。

上面的函数都是在定义该函数的作用域里调用,如f3 在f2定义并调用,f1在全局作用域里定义并在全局作用域调用,那么,如果在全局作用域调用,或是在别的函数里调用f3会有什么情况呢?下面我们试一下:



[c-sharp] view plaincopy
<mce:script type="text/javascript"><!-- 
var scope = "global"; 
var scope2 = "global-scope2" 
 
var f1 = function(){ 
    var scope = "function1"; 
    var scope2 = "function1-scope2"; 
    return (function(){ 
        var scope = "function2"; 
        return function(){ 
            alert(scope);  //will display function2 
            alert(scope2);  //will display function1-scope2 
        } 
         
    })(); 
     
     

 
var f4 = function(fun) 

    fun(); 

 
var f3 = f1(); 
 
 
f4(f3); 
// --></mce:script> 



上面的例子我们返回f3,并在f4里面调用f3,但结果没变,为什么呢?这是因为javascript的作用域包含关系是在函数定义的时候确定的,而不是在调用的时候确定的,所以不管在哪调用f3,函数的作用域包含关系都是: 全局作用域->f1->f2->f3。不过上面的这个例子还有另外一个作用域包含关系: 全局作用域->f4的作用域。

最后,还要说明的是,javascript没有块作用域,这点跟java,c++,c#,php等都是不同的,所以在循环语句里面创建的变量也是拥有函数调用作用域或是全局作用域的,并不会有临时变量存在。

注:
1.在javascript里,函数也是可以作为数据传递的,在上面的例子里用到了函数作用数据传递
2.上面的例子用到了闭包的知识,不清楚的朋友可以了解一下相关的知识


转自:http://blog.csdn.net/hzrui/article/details/3941137
分享到:
评论

相关推荐

    深入浅析JavaScript中的作用域和上下文

    JavaScript中,作用域和上下文是理解代码执行逻辑的关键概念。作用域指的是变量和函数的可见性和生命周期,而上下文则关乎`this`关键字的值,它指示了当前代码执行的环境。 **作用域(Scope)** 1. **全局作用域**...

    深化浅析JavaScript中的作用域和上下文_.docx

    JavaScript中的作用域和上下文是编程时必须理解的关键概念,特别是在JavaScript这种动态类型的脚本语言中。作用域决定了变量的可见性和生命周期,而上下文则与`this`关键字的值有关,它指定了当前执行代码的对象。 ...

    浅析JavaScript作用域链、执行上下文与闭包

    JavaScript 采用词法作用域(lexical scoping),函数执行依赖的变量作用域是由函数定义的时候决定,而不是函数执行的时候决定,通过本文给大家介绍JavaScript作用域链、执行上下文与闭包相关知识,感兴趣的朋友一起...

    浅析JavaScript中作用域和作用域链

    JavaScript中的作用域是编程语言中控制变量访问范围的规则,它决定了变量在何处可以被访问。在JavaScript中,主要有两种作用域:全局作用域和局部作用域。 1. **全局作用域**:全局作用域指的是在函数外部定义的...

    浅析js封装和作用域

    JavaScript中的作用域分为全局作用域和局部作用域。局部作用域又可以分为函数作用域和块作用域。 #### 1. 全局作用域 全局作用域中的变量和函数可以在代码中的任何位置被访问。全局作用域是顶级作用域。 #### 2. ...

    深入浅析javascript中的作用域(推荐)

    javascript(通常简称为js)作为一门运行在浏览器端的脚本语言,其核心作用域概念是前端开发者必须深刻理解的基础知识点之一。作用域定义了变量和函数的可访问范围,它决定了代码块内部以及外部对变量的访问权限。在...

    深化浅析JavaScript中数据共享和数据传递_.docx

    JavaScript中有三种主要的作用域:UI作用域、Page作用域和App作用域。 1. UI作用域:每个UI文件(如HTML模板)都有对应的一个UI.js文件,它们构成了一个封闭的作用域。在这个作用域内,可以基于UI组件ID获取对象,...

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

    主要介绍了浅析JavaScript中的变量复制、参数传递和作用域链 的相关资料,需要的朋友可以参考下

    浅析javascript语言中的函数闭包现象.pdf

    JavaScript中的函数闭包是一个重要的概念,它涉及到函数的作用域、变量持久化以及内存管理等多个方面。闭包的本质是在函数内部创建另一个函数,使得内部函数能够访问并操作外部函数的局部变量,即使外部函数已经执行...

    JavaScript中闭包之浅析解读(必看篇)_.docx

    JavaScript中的闭包是一种重要的编程概念,它涉及到函数和作用域的高级用法。闭包简单来说,就是一个函数能够访问并操作其外部作用域中的变量,即使在其外部函数已经执行完毕后,仍然能保持对外部作用域的访问权限。...

    浅析vue插槽和作用域插槽的理解

    本文将深入解析Vue插槽及其扩展形式——作用域插槽。 首先,让我们理解什么是普通插槽。插槽在Vue中是一个预留区域,它允许父组件向子组件注入自定义内容。在子组件的模板中定义一个插槽,然后父组件可以在使用子...

    深化浅析JavaScript中的Function类型_.docx

    7. **函数的其他特性**:JavaScript函数还支持闭包、作用域、原型链等高级特性。闭包允许函数访问并操作其外部作用域的变量,即使在其外部作用域已经销毁的情况下。作用域决定了变量的可见性和生命周期,而原型链则...

    Javascript闭包与函数柯里化浅析_.docx

    在JavaScript中,每当一个函数被创建,它都会形成一个作用域链,这个链包含了函数定义时的作用域以及包含它的所有外部作用域。当函数返回一个内部函数时,这个内部函数仍然保留对外部作用域的引用,形成了闭包。 ...

    Javascript变量函数浅析

    在JavaScript中,函数定义了一个作用域,在这个作用域中声明的任何变量和参数在函数外部都是不可见的,并且在整个函数中任何位置都可见: ```javascript var obj = { m: 'hello' }; var m = 'hi'; var say = ...

    浅析JavaScript中命名空间namespace模式_.docx

    本文将深入浅析JavaScript中的命名空间模式及其应用。 首先,命名空间的主要目的是限制全局变量的数量,因为过多的全局变量可能导致命名冲突,同时也影响代码的性能。通过使用命名空间,我们可以将相关的函数和对象...

Global site tag (gtag.js) - Google Analytics