JavaScript使用惯例

本文翻译自Christian Heilmann的博文《JavaScript best practices》。

原文地址:

http://dev.opera.com/articles/view/javascript-best-practices/

  想写一篇最好的实践文章往往是件很伤脑筋的事。大多数的你们一般都选择那些比较基础,平淡无奇的知识去练习。

  然而,看看web界,再结合这些年来自己从其他开发者所学到的一些代码,这些让我很直观的感觉在web里,活的代码简直就像是一件珍品。这是因为当你处于项目开发中,并且截止日期临近的时候,你会把“带着理性和逻辑做事”的编程习惯放到一个次要的地位。
因此,我想通过这篇最好的练习文章和我这些年来在web开发上所遇到的一些好的建议(这些经验可都是通过血的教训换来的哟)来让这一切都要容易。采用一些的建议,把她作为一个基本的原则记在你心里,这样你就可以在以后的开发中直接使用到。我也很肯定你会不同意里面的一些建议,这是好事--本来我们就应该质疑所看到的,并坚持能找到一个更好的解决方案。但我也更相信我自己,因为这些原则已经让我成为更具有效率的开发者,也同时让其他的开发者通过运用我的方式把工作变得更加容易。
  这篇文章的结构如下:

避免使用全局

使用全局变量和全局方法是一个不可取的想法。原因时每一个JavaScript文件都会包括在一个页面里,共存于同一个作用域。如果你代码里有全局变量或者方法,随着脚本文件的不断增多,很有可能在你以后的文件中难免会有相同的名称,这时,他们将会覆盖你以前定义的内容。

这里有几个变通的方法可采取。

首先假设你有一个变量和三个方法,如下:

var current = null;
function init(){...}
function change(){...}
function verify(){...}

你可采用下面的方式保护他们避免被覆盖:

var myNameSpace = {
  current:null,
  init:function(){...},
  change:function(){...},
  verify:function(){...}
}

这样你可以得到你想要的,但是这里也有一个缺点。为了调用其中的变量或方法,你总是需要通过主对象名称来访问,如 init()就是 myNameSpace.init(), current 就是myNameSpace.current 等等,这些都看起来重复而且很烦。

现在,这里有一个更好的办法解决这个问题,用一个匿名的方法去包含所有的内容并且保证他们在同一个作用域里。这就意味着你不必转换语法,把 function name() 写成 name:function() 了。这种窍门被称为组件模式:

myNameSpace = function(){
  var current = null;
  function init(){...}
  function change(){...}
  function verify(){...}
}();

再一次让你失望,这种方式也不是没有问题。现在,里面所有的成员对外都是不可见,因为他们只存在于当前的这个作用域,因此如果你想要让其中的一些方法作为公共的方法,你可以把他们放在一个返回表达式里:

myNameSpace = function(){
  var current = null;
  function verify(){...}
  return{
    init:function(){...}
    change:function(){...}
  }
}();

不仅如此,我们还可以对她进行进一步的改进:

myNameSpace = function(){
  var current = null;
  function init(){...}
  function change(){...}
  function verify(){...}
  return{
    init:init,
    change:change
  }
}();

和上面返回属性和方法不同,现在仅仅是返回的是他们的指针,这就使得外部要想访问其内部方法和变量变得更加方便和高效。同样,这样意味着你可以改变指针名字,让他对外显得更加不同,如:

myNameSpace = function(){
  var current = null;
  function init(){...}
  function change(){...}
  function verify(){...}
  return{
    init:init,
    set:change
  }
}();

现在调用 myNameSpace.set()将会调用 change()方法. 如果你更不想让内部所有的成员对外可见的话,你还可以定义另一个匿名父类对象去包含所有的内容:


(function(){
  var current = null;
  function init(){...}
  function change(){...}
  function verify(){...}
})();

上面的这些保证所有对象都在一个外部世界不能访问的包里,但又能保证在其内部能实现变量和方法能相互共享。

使用快捷的符号

Arrays 在JavaScript里是个很容易疑惑的地方,你可以在很多脚本里发现定义一个数组采用下面的方式:

var aweSomeBands = new Array();
aweSomeBands[0] = 'Bad Religion';
aweSomeBands[1] = 'Dropkick Murphys';
aweSomeBands[2] = 'Flogging Molly';
aweSomeBands[3] = 'Red Hot Chili Peppers';
aweSomeBands[4] = 'Pornophonique';

这上面有很多重复的地方,所以我们可以用[]作为数组定义的快捷方式:

var aweSomeBands = [
  'Bad Religion',
  'Dropkick Murphys',
  'Flogging Molly',
  'Red Hot Chili Peppers',
  'Pornophonique'
];

同样的列子:

var direction;
if (x > 100) {
    direction = 1;
} else {
    direction = -1;
}

可以用下面来代替:

var direction = (x > 100) ? 1 : -1;

还有一个例子,在JavaScript里,如果变量没有被定义,提供了一种可以对变量进行初始化的方法:

if (v) {
    var x = v;
} else {
    var x = 10;
}

可以简写为:

var x = v || 10;

posted on 2012-09-23 00:45  T船长  阅读(256)  评论(1)    收藏  举报

导航