(五)个人JavaScript系列:JavaScript的糟粕

泪眼问花花不语,乱红飞过秋千去。javascript

JavaScript的糟粕

JavaScript语言是一门集精华与糟粕于一体的语言。在JavaScript: the good parts中,便集中讨论了关于精华与糟粕的主题。有兴趣的同窗能够读读这本书,真的不错。基础不错的能够跳过前面的章节,直接进入附录的糟粕鸡肋的部分。我呢,就先在这本书里列举几个我感兴趣的糟粕部分与你们分享:java

全局变量

这恐怕是JavaScript当中最坑的部分了。先且不论全局变量的种种坏处了。在JavaScript中,定义一个全局变量是很轻松的一件事,能够经过下面的三种方式:编程

  1. 在函数外经过var定义:闭包

    var foo = value;函数

  2. 绑定到全局对象window:学习

    window.foo = value;this

  3. 在任何地方不经过var定义变量:.net

    foo = value;prototype

这里的准则就是通常不要在函数外定义变量(即使是经过var),定义变量时必定不能忘记var(但忘记var又是件很常见的错误)。code

做用域

JavaScript中的只有全局做用域和函数做用域两种,没有块做用域。同一个函数内的全部变量属于同一个做用域。例以下面的代码,foo的做用域不是if块,而是函数foo,因此在if块以外依然能够访问foo。

function f() {
  if(true) {
     var foo = 'foo';
  }
  console.log(foo); //依然能够访问foo
}

因此一种推荐的方式是在函数的顶部声明变量,就像C语言那样作。整个函数看上去就像下面的形式:

function f() {
  var a, b, c; //在函数顶部声明函数内使用的全部变量

  a = b = c = 2; //而后再使用变量
}

不过,像这样编程是一种很烦的方式。

自动插入分号机制

JavaScript会在每行末尾自动插入一个分号,只要语法容许。例以下面的代码

return
{ 
   status: true
};

会被转化为:

return;
{ 
   status: true
};

但下面的代码却不会(由于插入分号语法上不容许):

return {
   status: true
}

因此为了不理解上的歧义,JavaScript最佳实践建议手动加上分号,而不要依赖语言的自动插入分号机制。不过,现代语言(Ruby、Python等)基本都去掉分号行为了,每行代码都要加上个分号也是个烦人的事。

保留字

JavaScript上定义了不少但压根没用上的保留字,例如:abstract, boolean, byte, int

typeof

JavaScript的typeof每每文不对题,例如:

typeof null === 'object'

因此,用到typeof时,每每要多加当心。

浮点数

JavaScript中的数字没有整数类型,只有浮点数类型(实际为IEEE 754,即C语言的double类型)。众所周知,浮点数获得的结果是不精确的。不过好在浮点数表示的整数,它们之间的运算是精确的。

False值

JavaScript中,有不少值可以表示假值:

  1. 0
  2. NaN (非数)
  3. ‘’ (空字符串)
  4. false
  5. null
  6. undefined

因此,在使用if条件判断的时候,要适当注意下。

==

在JavaScript中,有两种形式的等号操做符:=====。其中==存在坑的地方。它在比较前,会先尝试进行类型转化再去比较。这里的问题在于,类型转化的规则太过复杂了,很难掌握。例如

'' == '0'    //false 
0 == ''      //true
0 == '0'    //true

===在比较的时候不会进行类型转化,只有类型相同和值相等的两个对象才会返回true。

缺乏块符号的语句

块符号,即{}。在JavaScript中,ifwhilefor内部的语句须要用大括号括起来。例外的状况是它们下面只有一条语句的时候。

if(ok)
  t = true;

不过这不是建议的方式。JavaScript最佳实践要求不管何种状况都要加上大括号,除非它们写在同一行。要么

if(ok) {
  t = true;
}

要么

if(ok) t = true;

第二种明显不怎么易看。

new语句

JavaScript的构造器函数须要经过new新建对象。若是忘记new,那它就是一个普通的函数调用,this被绑定到全局对象window。此时是很是危险的。

function Dog(name) {
  this.name = name;
}

Dog.prototype.bark = function() {
  return 'I am ' + this.name;
}

当调用构造器函数时,千万别漏掉new。JavaScript最佳实践甚至建议不要使用构造器函数,也就是不要经过new来新建对象。它的意思大概是像下面这样新建对象:

function dog(name) {
  var dog = {};
  dog.bark = function() {
     return 'I am ' + name;
  }
  return dog;
}

这是我之前常常用的一种方式。这里利用闭包的特性将name化为私有变量。一个很明显的缺点是bark函数被定义了屡次。

就该被遗忘的特性

下面的一些特性我历来没接触过,听说是坑人的特性。既然这样,我也不要去学习它们了。你们直接忽略它们就能够了。

  1. with语句
  2. eval函数
  3. ++ -- (不要a++,用a+=1替代)
  4. 位运算符 (& | ^ ~ >> <<)

相关资源

一些推荐的JavaScript学习教程

相关文章
相关标签/搜索