`
focus2008
  • 浏览: 26406 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

javascript中函数作用域和全局作用域

阅读更多
在地址:http://www.cnblogs.com/sharpxiajun/p/4133462.html看到一篇博客文章
谈谈javascript语法里一些难点问题(一)

其中有个例子:
var a = 1;
function hehe()
{
     window.alert(a);
     var a = 2;
     window.alert(a);
}
hehe();

结果是:先弹出 undefined, 在弹出 2.

对这个结果的解释,原文博主讲了很多,但是似乎没有讲到点子上。这里就使用“变量作用域”的概念就很好解释:外面 var a = 1; 定义了一个全局变量,函数hehe()里面定义了局部变量
var a = 2; 此时,全局变量 a 是无法进入函数 hehe()的作用域的,因为函数hehe()中已经定义了一个局部变量 var a = 2; 也就是说当函数中有变量和全局变量同名时,全局变量的作用域不能进入函数中,这个和C/C++中的处理是一样的,而Java更加严格,则根本就不允许在有覆盖的作用域中存在两个名字相同的变量名:
{
   int i;
   while(...){
       int i;
       // ...
   }
}

上面的Java报错:Duplicate local variable i

那么上面的结果的解释很简单:
因为hehe()函数中有变量a,所以全局变量的作用域不能进入hehe()函数中(其实在hehe函数中是有办法访问全局变量的,使用window.a;这个就是访问的全局变量a)而第一个alert(a)执行时,a只是在预加载准备执行环境时分配了栈空间,但是没有给他赋值,也没有让它指向堆上的某个对象,所以alert(a) 弹出:undefined.

所以:javascript中的define的含义是:进行过赋值操作!
var a; 这样只是声明,没有进行赋值,alert(a); 会弹出 undefined.
在看一个复杂的例子:
<script type="text/javascript">
var a = 1;
function hehe()
{
	alert(a);	// undefined
	alert(window.a);	// 1
	var a = 2;
	alert(a);	// 2
	var c;
	alert(c);	// undefined
	alert(b);	// ReferenceError: b is not defined (脚本终止继续执行)
	alert(1);	// 这里不会执行
}
hehe();

注意这里 alert(b)时报错:b is not defined

由这里可以引出 xx is not defined 和 undefined的区别
1)xx is not defined是没有声明,没有赋值;会导致脚本终止继续执行!!!
2)undefined是声明了,没有赋值;

还有 xxx function is not defined 错误也会终止脚本的继续执行。


那篇博客还提到了 不带var的赋值,因为作用域链机制,会成为全局变量:

fun f()
{
   a = 99;  // 这里是全局变量
}


-------------------------------------华丽的分割线----------------------------------
关于javascript的函数作用域和全局作用域,在网上看到一篇很好的文章,特转载过来
http://www.w3cfuns.com/article-5597357-1-1.html

JavaScript作用域

1.作用域
JavaScript的作用域与C、Java等语言不同,它不是以花括号包围的块级作用域,这个特性经常被大多数人忽视。例如下面代码,在大多数类C的语言中会出现变量未定义的错误,但在JavaScript中却完全合法:
if (true) {
    var msg = 'msg';
}
console.log(msg); // 输出 msg;

这是因为JavaScript的作用域完全是由函数来决定的,if、for语句中的花括号不是独立的作用域。

2.函数作用域
不同于大多数类C的语言,由一对花括号封闭的代码块就是一个作用域,JavaScript的作用域是通过函数来定义的,在一个函数中定义的变量只对这个函数内部可见,我们称为函数作用域。在函数中引用一个变量时,JavaScript会先搜索当前函数作用域,如果没有找到则搜索其上层作用域,一直到全局作用域。下面是一个简单的例子:
var scope = 'global';
var f1 = function() {
    console.log(scope);
}
f1(); // 输出 global

var f2 = function() {
    var scope = 'f2';
    console.log(scope);
}
f2(); // 输出 f2

以上示例十分明了,JavaScript的函数定义是可以嵌套的,每一层是一个作用域,变量搜索顺序是从内到外,按照作用域搜索顺序,在console.log函数访问scope变量时,JavaScript会先搜索函数f2的作用域,恰巧在f2的作用域里搜索到了scope变量,所以上层作用域中定义的scope就被屏蔽了。但下面这个例子可能就有些让人困惑:
var scope = 'global';
var f3 = function() {
    console.log(scope);
    var scope = 'f3';
}
f3(); // 输出 undefined

上面的代码可能和你的预想不一样,并没有输出global,而是undefined,这是为什么呐?这是JavaScript的一个特性,就是变量声明语句永远在该作用域里最先被执行,(其实可以将给特性理解成,变量声明,内存分配是在预加载时准备执行环境时完成的)所以上面的例子形同如下:
var scope = 'global';
var f4 = function() {
    var scope; // 变量声明最先被执行
    console.log(scope);
    scope = 'f4'; //变量被赋予值
}
f4(); // 输出 undefined

这样就不难理解运行f3()函数为什么没输出global,而是undefined了。

3.函数作用域的嵌套
一个作用域嵌套的例子:
var f5 = function() {
    var scope = 'first';
    (function() {
        var scope = 'second';
        (function() {
            console.log(scope);
        }());
    }());
}
f5(); // 输出 second

我们在最内层函数中引用到了scope变量,通过作用域搜索,找到了其父作用域中定义的scope变量。
有一点要注意:函数作用域的嵌套关系是在定义时决定的,而不是在调用时决定的,下面是一个简单的例子:
var scope = 'global';
var f6 = function() {
    console.log(scope);
}
var f7 = function() {
    var scope = 'f7';
    f6();
}
f7(); // 输出 global

这个例子中,通过f7调用的f6在搜索scope时,找到的是f6函数的父作用域中定义的scope变量,而不是f7中定义的scope变量。这说明了函数作用域的嵌套关系是在定义时决定的,而不是在调用时决定的。
分享到:
评论

相关推荐

    Web前端开发技术-认识函数作用域.pptx

    作用域划分:全局作用域、函数作用域和块级作用域(ES6提供的)。 不同作用域对应的变量:全局变量、局部变量、块级变量(ES6提供的)。 函数作用域 全局作用域 块级作用域 1.作用域分类 全局变量和局部变量 ...

    理解JavaScript作用域和作用域链

    作用域是JavaScript最重要的概念之一,想要...在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作用域:(1)最外层函数和在最外层函数外面定义的变量拥有全局作用域,例如:functiond

    深入理解JavaScript作用域和作用域链

    作用域是JavaScript最重要的...在JavaScript中,变量的作用域有全局作用域和局部作用域两种。 1. 全局作用域(Global Scope) 在代码中任何地方都能访问到的对象拥有全局作用域,一般来说一下几种情形拥有全局作用域: (1

    通过函数作用域和块级作用域看javascript的作用域链

    在ES6之前,javascript只有全局作用域和函数作用域。所谓作用域就是一个变量定义并能够被访问到的范围。也就是说如果一个变量定义在全局(window)上,那么在任何地方都能访问到这个变量,如果这个变量定义在函数...

    深入理解变量作用域

    全局(global)变量的作用域是全局性的,在javascript中,它的存在都有定义。而在函数之内声明的变量,就只在函数体内部有定义。它们是局部(local)变量,作用域是全局性的。函数的参数也是局部变量,它们只在函数体...

    JavaScript作用域示例详解

    作用域是JavaScript最...在JavaScript中,变量的作用域有全局作用域和局部作用域两种。 一、JavaScript中无块级作用域 在Java或C#中存在块级作用域,即:大括号也是一个作用域。 public static void main () { if

    JavaScript 作用域 和作用域链

    JavaScript 作用域 和作用域链作用域作用域链 作用域 作用域就是变量与函数的可访问范围,作用域控制...变量 str 在全局作用域没有声明,所以在全局作用域下取值会报错。作用域就是一个独立的盒子,让变量不会外泄、暴

    JavaScript函数作用域链分析

    本文实例分析了JavaScript函数作用域链。分享给大家供大家参考。具体分析如下: 作用域链: JavaScript的每个函数function都有自己的作用域,使用Active Object(简称AO)活动对象来保存,在相互嵌套的函数中形成了...

    javascript中的作用域和闭包详解

    1. 在同一作用域中,JavaScript是允许变量的重复定义,并且后一个定义将覆盖前一个定义。 2. 函数内部如果不加关键字var而定义的变量,默认为全局变量。 var scope="global"; function t(){ console.log(scope); ...

    JavaScript作用域与作用域链深入解析

    作用域是JavaScript最重要的...在JavaScript中,变量的作用域有全局作用域和局部作用域两种。 1. 全局作用域(Global Scope) 在代码中任何地方都能访问到的对象拥有全局作用域,一般来说一下几种情形拥有全局作用域: (1

    javascript 作用于作用域链的详解

    在JavaScript中,变量的作用域有全局作用域和局部作用域两种。 全局作用域(Global Scope) 在代码中任何地方都能访问到的对象拥有全局作用域,一般来说一下几种情形拥有全局作用域: (1)最外层函数和在最外层函数...

    javascript作用域和闭包使用详解

    作用域JavaScript 中有两种作用域:函数作用域和全局作用域。 在一个函数中声明的变量以及该函数的参数享有同一个作用域,即函数作用域。一个简单的函数作用域的例子: 代码如下:function foo() { var bar = 1; {...

    跟我学习javascript的作用域与作用域链

    作用域是JavaScript最重要的概念...在JavaScript中,变量的作用域有全局作用域和局部作用域两种。 1. 全局作用域(Global Scope)  在代码中任何地方都能访问到的对象拥有全局作用域,一般来说以下几种情形拥有全局作

    JavaScript作用域、闭包、对象与原型链概念及用法实例总结

    嵌套作用域变量搜索规则:当在函数中引用一个变量时,JS会搜索当前函数作用域,如果没有找到则搜索其上层作用域,一直到全局作用域。 var value = 'global'; var f1 = function(){ console.log

    JavaScript函数作用域

    什么是作用域 作用域是在运行代码是代码中的默写特定部分中的变量,函数和对象的可访问性,变量不是在所有地方都可以使用的,而这...全局作用域,不在任何函数中 var a = 20; function(){ var a =10; console.log(a)//

    JavaScript中的作用域链和闭包

    全局作用域(Global Scope) 在代码中任何地方都能访问到的对象拥有全局作用域,以下几种情形拥有全局作用域: 1、最外层函数和在最外层函数外面定义的变量拥有全局作用域,例如: 代码如下: var ou

    JavaScript 作用域scope简单汇总

    ES6之前,JavaScript作用域有两种:函数作用域和全局作用域。 ES6之后,JavaScript新增了块级作用域。 作用域的特性 在JavaScript变量提升的讨论中,我们其实是缺少了一个作用域的概念的,变量提升其实也是针对在...

    js作用域和作用域链及预解析

    局部作用域和全局作用域 js中没有块级作用域—一对括号中定义的变量,这个变量可以在大括号外面使用 函数中定义的变量是局部变量 作用域链:变量的使用,从里向外,层层的搜索,搜索到了就可以直接使用了 层层搜索,搜索到...

    javaScript函数式编程

    3.1 全局作用域44 3.2 词法作用域46 3.3 动态作用域47 3.4 函数作用域51 3.5 闭包52 3.5.1 模拟闭包53 3.5.2 使用闭包57 3.5.3 闭包的抽象59 3.6 总结60 第4章 高阶函数62 4.1 以其他函数为参数的函数62 4.1.1 关于...

Global site tag (gtag.js) - Google Analytics