全局变量

javaScript通过函数管理变量作用域。在函数内部声明的变量只在这个函数内部可用,函数外面不可用。另一方面,在任何函数外面声明的或是函数内未声明直接使用的变量叫做全局变量。

每个JavaScript环境有一个全局对象,当你在任意的函数外面使用this的时候可以访问到。你创建的每一个全局变量都成了这个全局对象的属性。

在浏览器中,全局对象有个附加属性叫做window,它表示浏览器的窗口,所有函数和全局变量均自动成为window的成员。下面的代码片段显示了如何在浏览器环境中创建和访问的全局变量:

myglobal = "hello"; // 不推荐写法
console.log(myglobal); // "hello"
console.log(window.myglobal); // "hello"
console.log(window["myglobal"]); // "hello"
console.log(this.myglobal); // "hello"

全局变量的问题在于,你的JavaScript应用程序和web页面上的所有代码都共享了这些全局变量,他们住在同一个全局命名空间,所以当程序的两个不同部分定义同名但不同作用的全局变量的时候,命名冲突在所难免。

web页面包含不是该页面开发者所写的代码也是比较常见的,例如:

  • 第三方的JavaScript库
  • 广告方的脚本代码
  • 第三方用户跟踪和分析脚本代码
  • 不同类型的小组件,标志和按钮

比方说,该第三方脚本定义了一个全局变量,叫做result;接着,在你的函数中也定义一个名为result的全局变量。其结果就是后面的变量覆盖前面的,第三方脚本就会失去效果!

因此,要想和其他脚本成为好邻居的话,尽可能少的使用全局变量是很重要的。后面会提到的一些减少全局变量的策略,例如命名空间模式或是函数立即自动执行,但是要想让全局变量少最重要的还是始终使用var来声明变量。

由于JavaScript的两个特征,不自觉地创建出全局变量是出乎意料的容易。首先,你可以甚至不需要声明就可以使用变量;第二,JavaScript有隐含的全局概念,意味着你不声明的任何变量都会成为一个全局对象属性。参考下面的代码:

function sum(x, y) {
   // 不推荐写法: 隐式全局变量
   result = x + y;
   return result;
}

此段代码中的result没有声明。代码照样运作正常,但在调用函数后你最后的结果就多一个全局变量,这可以是一个问题的根源。经验法则是始终使用var声明变量,正如改进版的sum()函数所演示的:

function sum(x, y) {
   var result = x + y;
   return result;
}

隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力。

  • 通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。
  • 无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。

这表明,在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性。属性是可以通过delete操作符删除的,而变量是不能的:

// 定义三个全局变量
var global_var = 1;
global_novar = 2; // 反面教材
(function () {
   global_fromfunc = 3; // 反面教材
}());

// 试图删除
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true

// 测试该删除
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"

函数作用域和声明提前

在类似c语言的编程语言中,花括号({})内的每一段代码都具有自己的各自作用域,而且变量声明在他们的代码段之外是不可见的,我们称之为块级作用域。js中则没有块级作用域。去而待之的是函数作用域,变量在声明它的函数体以及这个函数体嵌套的任意函数体内都是有定义的。

如下代码中:在不同的位置定义了变量i、j、和k,它们都在同一个作用域内——这三个变量在函数体内均是有定义的:

function test(o){
    var i=0;
    if(typeof o=="object"){
        var j=0;
        for(var k=0; k<10; k++){
            console.log(k);
        }
        console.log(k);
    }
    console.log(j);
}

javascript的函数作用域是指在函数内声明的所有变量在函数体内始终是可见的。有意思的是,这意味着变量在变量在声明之前甚至已经可用。javascript的这个特性被非正式的称为“声明提前”:即javascript函数里声明了所有的变量(但不涉及赋值)都被”提前“至函数体的顶部。
如下代码:

var scope = "global";
function f(){
    console.log(scope);
    var scope="local";
    consloe.log(scope);
}

你可能误以为函数的第一行会输出“global”,因为代码还没有执行到var语句声明局部变量的地方,其实不然,由于函数作用域的特性,局部变量在整个函数体始终是有定义的,也就是说,在函数体内局部变量遮盖了同名的全局变量。尽管如此,只有在程序执行到var语句的时候,局部变量才会真正地赋值。因此,上述过程等价于:将函数内的变量声明“提前”至函数体顶部,同时变量初始化留在原来的位置:
代码:

function f(){
    var scope;
    console.log(scope);
    scope="local";
    console.log(scope);
}

在具有块级作用域的编程语言中,在狭小的作用域里让变量声明和使用变量的代码尽可能靠近彼此,通常来讲,这是个非常不错的编程习惯。由于javascript没有块级作用域,因此一些程序员特意将变量声明放在函数体顶部,不是声明在靠近使用变量之处。这种做法是得他们的源代码非常清晰地反映了真实的变量作用域。

命名规范

对于构造函数,可以使用大驼峰式命名法(upper camel case),如MyConstructor()。对于方法名称和变量,你可以使用小驼峰式命名法(lower camel case),像是myFunction(), calculateArea()getFirstName()

JavaScript中没有定义常量的方法(尽管有些内置的像Number, MAX_VALUE),所以开发者都采用全部单词大写的规范来命名这个程序生命周期中都不会改变的变量,如:

// 珍贵常数,只可远观
var PI = 3.14,
    MAX_WIDTH = 800;

还有另外一个完全大写的惯例:全局变量名字全部大写。全部大写命名全局变量可以加强减小全局变量数量的实践,同时让它们易于区分。

另外一种使用规范来模拟功能的是私有成员。虽然可以在JavaScript中实现真正的私有,但是开发者发现仅仅使用一个下划线前缀来表示一个私有属性或方法会更容易些。考虑下面的例子:

var person = {
    getName: function () {
        return this._getFirst() + ' ' + this._getLast();
    },

    _getFirst: function () {
        // ...
    },
    _getLast: function () {
        // ...
    }
};

编写高质量JavaScript代码的基本要点的更多相关文章

  1. 深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点

    深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 2011-12-28 23:00 by 汤姆大叔, 139489 阅读, 119 评论, 收藏, 编辑 才华横溢的 ...

  2. 编写高质量JavaScript代码的基本要点记录

    原文:深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 1.最小全局变量(Minimizing Globals)的重要性 JavaScript通过函数管理作用域.在 ...

  3. <深入理解JavaScript>学习笔记(1)_编写高质量JavaScript代码的基本要点

    注:本文是拜读了 深入理解JavaScript 之后深有感悟,故做次笔记方便之后查看. JQuery是一个很强大的JavaScript 类库,在我刚刚接触JavaScript的就开始用了. JQuer ...

  4. 高质量JavaScript代码书写基本要点

    翻译-高质量JavaScript代码书写基本要点 by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/ ...

  5. 编写高质量JavaScript代码的68个有效方法

    简介: <Effective JavaScript:编写高质量JavaScript代码的68个有效方法>共分为7章,分别涵盖JavaScript的不同主题.第1章主要讲述最基本的主题,如版 ...

  6. 高质量JavaScript代码书写基本要点学习

    高质量JavaScript代码书写基本要点学习 可维护的代码意味着: •可读的 •一致的 •可预测的 •看上去就像是同一个人写的 •已记录   最小全局变量(Minimizing Globals)   ...

  7. [转] 翻译-高质量JavaScript代码书写基本要点 ---张鑫旭

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=1173 原文作者:St ...

  8. 编写高质量JavaScript代码绳之以法(The Essentials of Writing High Quality JavaScript)翻译

    原文:The Essentials of Writing High Quality JavaScript 才华横溢的Stoyan Stefanov,在他写的由O'Reilly初版的新书<Java ...

  9. 如何编写高质量JavaScript代码

    书写可维护的代码(Writing Maintainable Code ) 软件bug的修复是昂贵的,并且随着时间的推移,这些bug的成本也会增加,尤其当这些bug潜伏并慢慢出现在已经发布的软件中时.当 ...

随机推荐

  1. 以一则LUA实例说明敏捷开发中“分离构造和使用”原则

    分离构造和使用 构造含义是功能的实现, 此功能是一个定义明确的处理过程, 开放出明确的接口给调用者使用. 则使用者可以直接调用接口进行使用, 但是使用者需要搞清楚, 那些是构造, 那些是使用. 不要再 ...

  2. RDIFramework.NET ━ 9.14 数据库连接管理 ━ Web部分

    RDIFramework.NET ━ .NET快速信息化系统开发框架 9.14  数据库连接管理 -Web部分 我们经常可以看到很多软件直接把数据库连接字符串放在软件执行目录下的配置文件中,这种直接把 ...

  3. SQLite Expert 删除表数据并重置自动增长列

    用下面的语句肯定是行不通的,语句不支持 truncate table t_Records 方法:1.删除表数据 2.重置自动增长列 where name='t_Records' /*name :是表名 ...

  4. C++学习笔记(1)——数据类型占空间大小

    boolean bool 1 byte   character char 1 byte May be signed or unsigned   wchar_t 1 byte     char16_t ...

  5. html,移动端代码

    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale= ...

  6. MSDeploy

    http://blogs.iis.net/jamescoo/default.aspx   Web Deployment Tool Now Works With Credential Store Feb ...

  7. ReactiveCocoa常见操作方法介绍/MVVM架构思想

      1.ReactiveCocoa常见操作方法介绍. 1.1 ReactiveCocoa操作须知 所有的信号(RACSignal)都可以进行操作处理,因为所有操作方法都定义在RACStream.h中, ...

  8. Python—进程、线程、协程

    一.线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 方法: ...

  9. 利用ksoap调用webservice

    博文参考: http://www.cnblogs.com/shenliang123/archive/2012/07/05/2578586.html http://blog.csdn.net/jimbo ...

  10. 我对于MSP的理解,供参考

                                   本人在项目管理圈儿也算是摸爬滚打了几载,近几年真是各种压力大,看同行们各种参加培训.认证......我也不能懈怠啊,赶紧上网搜搜相关的培训 ...