javascript糟粕与鸡肋分析

  “大多数语言都有精华部分和鸡肋部分,我发现如果只使用精华部分而避免使用鸡肋部分,我可以成为一名更好的程序员”,Douglas Crockford曾经写过一本很薄的书《JavaScript: The Good Parts》,这是开篇中的一句话。书中专门介绍了JavaScript中值得发扬光大的精华部分,并在附录中详细列举了JavaScript的糟粕、鸡肋部分。如果能规避掉JavaScript语言中怪癖、缺陷的部分,将最终使编程更轻松、程序更健壮。

       下面我们要谈的就是JavaScript的糟粕与鸡肋部分,因为糟粕与鸡肋部分相比精华部分要少,而且更容易记忆,我们在写代码时规避了糟粕与鸡肋部分,自然得到的全部都是精华部分。

       糟粕部分

  1. 全局变量

JavaScript最糟糕的就是它对全局变量的依赖性。全局变量就是在所有作用域中都可见的变量,其在很小的程序中可能会带来方便,但随着程序越来越大,其很快变得难以处理。因为一个全局变量可以被程序的任何部分在任意时间改变,它们会使得程序的行为被极大的复杂化,降低程序可靠性。

  1. 作用域

JavaScript的语法来源于C, 但没有提供C语言一样的块级作用域,即代码块中声明的变量在包含此代码块的函数的任何位置都是可见的。建议在每个函数的开头部分声明所有变量。

  1. 保留字

JavaScript语言大多数的保留字并没有在语言中使用,它们不能被用来命名变量或参数。当保留字被用作对象字面量的键值时,它们必须被引号括起来。它们不能被用在点表示法中,所以有时必须使用括号表示法。

  1. typeof

typeof运算符返回一个用于识别其运算数类型的字符串,所以

typeof 98.6

返回’number’。不幸的是:

        Typeof null

返回’object’而不是’null’, 更好的检测null的方式是  my_value === null,

typeof 'str' //返回string

typeof new String('str') //返回object

所以不推荐使用typeof 来查看变量类型。

解决的办法是使用 Object.prototype.toString.call('str')来代替,返回"[object String]", 适用于字符串,数值、数组、正则表达式,undefined,null 等所有类型。

  1. parseInt

parseInt用于将字符串转为整型数值,如果不指明第二个参数(进制)时,可能会返回意外情况,如

parseInt('010') 返回 8

为防止此问题出现,在使用时需要指定转为什么进制,

parseInt('010', 10) 返回10

  1. NaN

NaN 是IEEE 754中定义的一个特殊的数量值。它表示不是一个数字,但下面的表达式返回的是true,

Typeof NaN === ‘number’  // true

而且,

NaN === NaN  // false

NaN !== NaN  // true

在数字判断与运算时会产生意想不到的结果。

  1. 假值

JavaScript拥有令人惊讶的一大组假值:

0             Number

NaN(非数字)   Number

''(空字符串)  String

false         Boolean

null          Object

undefined     Undefined

这些值全部都等同于假,但它们是不可互换的。如何使用会强制类型转换的==运行符,而不是更可靠的===运算符,有时结果可能出现混乱。

 

 

       鸡肋部分

  1. ==

"" == "0"   // false

0  == ""   // true

0  == "0"  // true

false  == "false"  // false

false  == "0"     // true

false  == undefined  // false

false  == null       // false

null   == undefined  // true

" \t\r\n" == 0        // true

所以推荐使用 ===和!==

  1. with语句

JavaScript提供了一个with语句,本意是想用来快捷地访问对象的属性。不幸的是,它的结果可能有时是不可预料的。单单从with语句块内部难以区分变量所属关系,而且其本身也严重影响了JavaScript处理器的速度,因为它阻止了变量名的词法作用域绑定,所以应该避免使用它。

  1. eval和Function构造器

eval函数传递一个字符串给JavaScript编译器,并且执行其结果。eval函数减弱了你的应用的安全性,因为它给被执行的文本授予了太多的权力,且不是完全可控。而且像with语句执行的方式一样,它降低了语言的性能。Function构造器是eval的另一种形式,当setTimeout 和 setInterval接受的是字符串参数时也会像eval那样去处理,所以它们同样也应该被避免使用。

  1. 缺少块语句

If、while、do或for语句可以接受一个括在花括号中的代码块,也可以接受单行语句。单行语句的形式是另一种带刺的玫瑰。它带的来好处是可以节省两个字节,但它模糊了程序的结构,使得在随后的操作代码中可以很容易插入错误。

  1. ++ 与 --

自增与自减运算符使得程序员可以用非常简洁的风格去编码。当我们使用++和--时,代码往往变得过于紧密、复杂和隐晦,事实上,这两个运算符容易促成一种不谨慎的编程风格。大多数的缓冲区溢出错误所造成的安全漏洞,都是由于像这样的编码而导致的。避免使用它们,会让我们的代码风格变得更为整洁。

  1. 位运算符

JavaScript有着与Java相同的一套位运算符。在Java里,位运算符处理是的整数。JavaScript没有整数类型,它只有双精度的浮点数。因此,位操作符将它们的数字运算先转换成整数,接着执行运算,然后再转换回去。在大多数语言中,这些位运算符接近于硬件处理而非常快。在JavaScript中,它们非但不是硬件处理,而且非常慢。JavaScript很少被用来执行位操作。

  1. function语句对比函数表达式

function语句格式: function foo(){ }

函数表达式格式:  var foo = function(){ }

function语句在解析时会发生被提升的情况,这意味着不管function被放置在哪里,它会被移动到被定义时所在的作用域的顶层。这放宽了函数必须先声明后使用的要求,而这可能会导致混乱。在if语句中使用function语句也是被禁止的。结果表明大多数的浏览器都允许在if语句里使用function语句,但它们在解析时的处理上各不相同。那就造成了可移植性的问题。所以建议使用函数表达式方式定义函数。

  1. 类型的包装对

JavaScript有一套类型的包装对象,如:new Boolean(false)

会返回一个对象,该对象有一个valueOf 方法会返回被包装的值。这其实完全没有必要,并且有时不令人困惑。不要使用 new Boolean、new Number或new String 。

此外也请避免使用 new Object 和 new Array。可直接使用 {}和[]来代替。

  1. new

JavaScript的new 运算符创建一个继承于其运算数的原型的新对象,然后调用该运算数,把新创建的对象绑定给this。这给运算数(它应该是一个构造器函数)一个机会在返回给请求者前去自定义新创建的对象。如果你忘记了使用此new运算符,你所得到的就是一个普通的函数调用,并且this被绑定到全局对象,而不是新创建的对象。那意味着当你的函数尝试去初始化新成员元素时它将会污染全局变量。按照惯例,打算与new结合使用的函数应该命名为首字母大写的形式,并且首字母大写的形式应该只用来命名那些构造器函数。这个约定给我们提供了一个视觉线索,以帮助我们发现那些JavaScript语言自身经常忽略但却会带来昂贵代价的错误。一个更好的应对策略就是根本不去使用new。

 

以上是我们在日常用JavaScript语言开发过程中经常遇到的情况,希望大家在遇到这些问题的时候遵循所给出的规则和建议,使用正确的解决方法,使我们的程序更可靠、健壮。

 

来源:http://jack.datamm.com/post/javascript/traps_and_bad_parts_of_javascript.html

加支付宝好友偷能量挖...


评论(0)网络
阅读(148)喜欢(1)JavaScript/Ajax开发技巧