开始

一个变量的作用域(scope)是程序源代码中定义这个变量的区域。全局变量具有全局作用域,在javascript中的任何地方都是有定义的。然而在函数内申明的变量只在函数体内有定义。他们是局部变量,作用域是局部性的。函数参数也是局部变量,他只在函数体内有定义。下面就来看看我在这几个方面做的尝试与测试。

1.全局变量可以被任何地方访问到,而局部变量则不行。我们来看看下面的代码:

  1. var global = "global";
  2. function f(){
  3. var local = "local";
  4. alert(global); //==>"global" 全局变量可以被访问的
  5. }
  6. f();
  7. alert(local); //==> 报错:local is not defined

2.尽管全局变量可以不用var申明,但是局部变量就一定要用var申明。否则的话,如果申明的局部变量与一个全局变量重名的情况下就会修改这个全局变量,如果没有与之重名的全局变量就会申明一个全局变量。我们来看看下面的代码:

  1. function f(){
  2. local = "local"; //没有用var申明,相当于申明了全局变量
  3. }
  4. f();
  5. alert(local); //==> "local"
  6.  
  7. var global = "global";
  8. function f2(){
  9. global = "local"; //没有用var申明并且有与之重名的global全局变量相当于修改了global全局变量
  10. }
  11. f2();
  12. alert(global); //==> "local"

3.在函数体内,局部变量的优先级要高于同名的全局变量。如果在函数体内申明的一个局部变量或者函数参数中带有变量和全局变量重名,那么全局变量就会被拘捕变量覆盖。我们来看看下面的代码:

  1.    var scope = "global"; //申明一个全局变量
  2. function f(){
  3. var scope = "local"; //申明一个同名的局部变量
  4. alert(scope);
  5.   }
  6. f(); //==> "local"

4.函数体内全局变量的申明提前。说道申明提前,可能比较陌生。我们就来看一下一道经典的javascript面试题:

  1. var scope = "global";
  2. function f(){
  3. alert(scope);
  4. var scope = "local";
  5. alert(scope);
  6. }
  7. f();

也许你会误以为函数中的第一行会输出"global",因为代码还么有运行到var语句申明局部变量的地方。其实不然,由于函数作用域的特性,局部变量在整个函数体始终是定义的,也就是说,在函数体内的局部变量覆盖了全局变量,只有在var语句执行是才给其赋值。所以代码等同于以下代码:

  1. function f2(){
  2. var scope;
  3. alert(scope); //undefined
  4. scope = "local"; //local
  5. alert(scope);
  6. }
  7. f2();

明白了吧,所以有经验的程序员都会将函数体内的申明都会提前到前面,这是一种良好的编码习惯。

5.那么函数参数和申明的局部变量重名的情况呢?

  1. function f(t){
  2. alert(t);
  3. var t;
  4. alert(t)
  5. }
  6. function f2(t){
  7. alert(t);
  8. var t = 30;
  9. alert(t);
  10. }
  11. f(20);
  12. f2(20);

看一下运行结果:f()-->20 , 20;  f2()-->20 , 30;

这是什么原因呢?我总结了一下:在函数参数和局部变量重名的情况下,如果局部变量只是申明了,但是没有赋值,局部变量是不会覆盖参数的。如果局部变量赋值了,就从赋值的那一行起,向下覆盖参数变量。

通过以上的发现是不是明了许多了?其实javascript入门容易,但是精通难。所以大家一起共勉进步吧。最后引用一下《javascript权威指南》为本文做一下总结:"javascript最顶层的代码中(也就是不包含在任何函数定义的代码),作用域链由一个全局对象组成。在不包含嵌套的函数体内,作用域链上有两个对象,第一个是定义函数参数和局部变量的对象,第二个是全局对象。当定义一个函数时,他实际上保存了一个作用域链。当调用这个函数时,他创建一个新的对象来存储他的局部变量,并将这个对象添加至保存的那个作用域上,同事创建一个新的更长的表示函数用用作用域的‘链’"

=============低调的分割线==============

关于javascript变量作用域的研究。的更多相关文章

  1. 【转】javascript变量作用域、匿名函数及闭包

    下面这段话为摘抄,看到网上大多数人使用的是变量在使用的时候声明而不是在顶端声明,也可能考虑到js查找变量影响性能的问题,哪里用就在哪里声明,也很好. 在Javascript中,我们在写函数的时候往往需 ...

  2. php中include文件变量作用域的研究

    原文:php中include文件变量作用域的研究 在php中我们有时候需要include一个文件.比如我前段时间在写一个框架的时候,打算用原生的php作为模板,然后写一个display方法引入模板文件 ...

  3. 第一百零六节,JavaScript变量作用域及内存

    JavaScript变量作用域及内存 学习要点: 1.变量及作用域 2.内存问题 JavaScript的变量与其他语言的变量有很大区别.JavaScript变量是松散型的(不强制类型)本质,决定了它只 ...

  4. JavaScript 变量作用域

    一. 变量声明 变量用var关键字来声明,如下所示: 变量在未声明的情况下被初始化,会被添加到全局环境. JavaScript执行代码时,会创建一个上下文执行环境,全局环境是最外围的环境.每个函数在被 ...

  5. JavaScript变量作用域

    全部变量拥有全局作用域,局部变量拥有局部作用域(这里注意函数的参数也是局部变量) 1.在函数体内,局部变量的优先级高于同名的全局变量. 我的理解就是当你同时定义了同名的局部变量和全局变量时,函数体内返 ...

  6. 深入理解Javascript变量作用域

    在学习JavaScript的变量作用域之前,我们应当明确几点: a.JavaScript的变量作用域是基于其特有的作用域链的. b.JavaScript没有块级作用域. c.函数中声明的变量在整个函数 ...

  7. JavaScript 变量作用域 详解

    变量作用域要点 - 在JavaScript中没有块级作用域,只有函数作用域 - 在函数体内,局部变量的优先级高于同名的全局变量 - 在全局作用域编写代码时可以不写var语句,但声明局部变量时必须使用v ...

  8. JavaScript变量作用域(Variable Scope)和闭包(closure)的基础知识

    在这篇文章中,我会试图讲解JavaScript变量的作用域和声明提升,以及许多隐隐藏的陷阱.为了确保我们不会碰到不可预见的问题,我们必须真正理解这些概念. 基本定义 作用范围是个“木桶”,里面装着变量 ...

  9. 基础系列(1)之干掉JavaScript变量作用域

     今天去某顺公司面试,发现一些基础知识都不记得了,于是乎决定把js基础系列的全部梳理一遍,今天就整理下js变量作用域的相关基础知识点,配合最常遇到的笔试题阐述. 题一: var g = "a ...

随机推荐

  1. Python 3.3 try catch所有的错误Error,不包括Exception。关键在于 sys.exc_info()

    import os; import sys; #---------------------------------------------- def main( ) : try : a = 1 / 0 ...

  2. Visual Studio 2013进行单元测试

    使用Visual Studio 2013进行单元测试--初级篇   1.打开VS2013 --> 新建一个项目.这里我们默认创建一个控制台项目.取名为UnitTestDemo 2.在解决方案里面 ...

  3. LINUX下getsockopt和setsockopt函数

    这两个函数仅用于套接字. 函数原型: #include <sys/socket.h> #include <sys/types.h> int getsockopt(int soc ...

  4. 在Ubuntu中编译QT工程Tesful

    今天晚上开机到Ubuntu中了,试了一下之前在Windows下建立的Tesful工程,发现没有任何改动就可以编译成功/运行. 附上图:

  5. Objective C多态

    面向对象的封装的三个基本特征是.继承和多态. 包是一组简单的数据结构和定义相关的操作在上面的其合并成一个类,继承1种亲子关系,子类能够拥有父类定的成员变量.属性以及方法. 多态就是指父类中定义的成员变 ...

  6. JQUERY 插件开发——MENU(导航菜单)

    JQUERY 插件开发——MENU(导航菜单) 故事背景:由于最近太忙了,已经很久没有写jquery插件开发系列了.但是凭着自己对这方面的爱好,我还是抽了一些时间来过一下插件瘾的.今天的主题是导航菜单 ...

  7. Metro UI 界面完全解析 (转载)

    Metro在微软的内部开发名称为“ typography-based design language”(基于排版的设计语言).它最早出现在微软电子百科全书95,此后微软又有许多知名产品使用了Metro ...

  8. RESTful API Develop

    yii2 RESTful API Develop   参考文档:http://www.yiiframework.com/doc-2.0/guide-rest.html 以 DB 中的 news 表为例 ...

  9. Flex 弹性盒模型

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. Js 数组(一):基础应用

    (一) Js 数据类型 分为基本数据类型以及引用类型 基本数据类型有 null,undefined,Boolen,Number,String,还有一种复杂数据类型 Object. var var1 = ...