如果刚开始学习JavaScript,无论完全自己写程序,或者使用一些框架 (jQuery, Mootools, Dojo, YUI) ,下面这几个错误你必须要避免, 它们都是我学习JavaScript的经验之谈。
等价比较(Equality Operator)
JavaScript中有两个相等比较操作符.第一个就是两个等于号(==),它只比较值是否相等,而不关心数据类型。例如,当比较1和true时,结果为true.
if(1==true){
//这部分代码会被运行
}
以下是几个不同的例子.
1 == "1" //true "true" == true //false 1 == true //true "0" == 0 //true "" == 0 //true " " == 0 //true "Str" == false //false "Str" == true //false
如果不了解javaScript的==操作符,其中一些结果可能有点出乎意料.事实上它们都被转换成Number类型进行比较的.
比如第一个例子 (1== “1″).左边已经是一个数值了,不需要转换.右边是一个字串,它会被转为数值1.
第二个例子(“true”== true)结果为false是因为字串包含的是字符,而不是数字符号,它会被转为NaN,表示Not a Number. 任何值同NaN相比,结果就是false.
可以使用Number构造函数来检查转换的结果。下面是使用FireBug测试的结果.
三个等于号的全等比较符,除了比较值之外,还会比较数据类型.如果数据类型也不同,结果就是false.只有当数据类型和值都相同时结果才为true.
4===4 //true "2"===2 //false 1===true //false "true"===true //false
不为引用类型赋NULL
当引用类型变量(object or Array)不再使用时,没有给它赋NULL是一个常见的错误.看看下面的例子:
var arr=[1,2,3]; //执行一些操作 //当不再使用时,赋NULL arr =null;
这样做最大的好处就是可以让JavaScript引擎的垃圾回收器可以及时释放被占用的内存.如果变量的作用域近似于全局变量,及时赋NULL就很重要了.局部变量会在离开作用域时被自动解构(特别是使用Mark and Sweep垃圾回收( garbage collector )算法的引擎, WebKit使用的就是这种算法.).
引用类型变量的初始化 (Reference Variable Initialization)
永远不要在单行赋值语句中为多个引用类型变量(object and array)赋值.用下面的例子可以更好地理解.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var arr1=[1,2,3] , arr2=['a','b','c'];
//重置两个数组 arr1 = arr2=[]; //为两个数组各增加一项 arr2.push(32); arr1.push(10);
//输出看到相同的结果//OUTPUT: 10, 32 alert( arr1.join()); alert( arr2.join()); |
第1行和第2行分别创建了两个数组.然后在第5号它们都被清空了,但这个语句的问题是同时把arr1和arr2都指向了相同的数组,而不再是之前各自独立的数组. 所以改变其中一个就也自动体现到另一个.
在第8行为arr2增加了32,在第9行,为arr1增加了一个10.通过检查13行和14行的输出结果可以看到两个数组有相同的内容.
不要忘记使用var
在JavaScript中,可以使用var定义变量, 但是也可以不使用var直接定义. 这两种方式有很大的不同.看看下面的例子:
function createVar(){ var myVar='local'; }; alert( myVar );//输出:undefined
上面例子中有一个使用var定义的变量myVar, 它在函数外就无法访问了.下面的例子将不使用var定义变量.
function createVar(){ myVar ='local'; }; alert( myVar );//输出:local
可以看到不使用var定义的变量myVar在全局作用域也可以访问. 换句话说var定义的是局部变量.在JavaScript声明变量一定要小心,尽量在使用它们前用var来声明.
没有使用事件代理 (Not Using Event Delegation)
JavaScrip中加入(attach)一个事件处理程序很容易. 下面的例子就为指定ID的元件指定了一个click事件处理程序.
document.getElementById('myLink').addEventListener('click',function(){
//you code goes here...},false);
假设你要为所有的td元件增加一个click事件处理程序.需要为表中的每个td项写一个处理程序吗?
<table id="myTable"> <tbody> <tr> <td>1, 1</td> <td>1, 2</td> </tr> <tr> <td>2, 1</td> <td>2, 2</td> </tr> </tbody> </table>事件代理程序可以简化这件事.为整个表myTable指定一个clikc事件处理程序,然后在其内容检查是不是某个td被点击了.这样就不需要为每个td项指定事件处理程序了, 这样的程序就是所谓的事件代理.下面是它的代码:
document.getElementById( 'myTable' ).addEventListener( 'click', function( e ) { if( e.target && e.target.nodeName == 'TD' ) { console.log( e.target.innerHTML ); //to access id //console.log( e.target.id ); //to access className //console.log( e.target.className ); } }, false );
innerText与 innerHTML
JavaScript开发的新丁常常会搞混innerText和innerHTML.它们都由DOM元件调用. innerHTML将取得元件内部的HTML代码,而innerText只是取得元件中的文本内容.
Html中的黑色的部分将是innerHTML属性的输出结果.其中HTML标签<p>也被输出了.
再来看一个innerText的例子.
可以看到innerText只取得了文本内容,而没有HTML标签..
批量添加节点(Adding Nodes in Bulk)
为DOM元件添加一系列节点是比较普遍的.比如将Ajax调用返回的名字列表加入到ul元件中.下面是一种做法:
window.onload = function() { //ul element - <ul id="list"></ul> var list = document.getElementById( 'list' ); var item = null; //假设调用Ajax返回的是json数据 var ajaxResponse = [ { 'name' : 'Haiku' }, { 'name' : 'Linux' }, { 'name' : 'OS X' }, { 'name' : 'Windows' } ]; //添加名字列表到document中 for( var i in ajaxResponse ) { item = document.createElement( 'li' ); item.appendChild( document.createTextNode( ajaxResponse[ i ].name ) ); list.appendChild( item ); } } //end onload /* ..:: 输出 ::.. <ul id="list"> <li>Haiku</li> <li>Linux</li> <li>OS X</li> <li>Windows</li> </ul> */
“DocumentFragment 是一个轻量级的document,而且不会直接显示在网页上.”
相同的结果也可以使用DocumentFragment达到, 而且只在最后更新到网页,从而不致对网页影响太大.下面就是改写的例子.
window.onload = function() { //创建DocumentFragment var documentFragment = document.createDocumentFragment(); var list = document.getElementById( 'list' ); //<ul id="list"></ul> var item = null; //假设调用Ajax返回的是json数据 var ajaxResponse = [ { 'name' : 'Haiku' }, { 'name' : 'Linux' }, { 'name' : 'OS X' }, { 'name' : 'Windows' } ]; //添加所有名字到documentFragment for( var i in ajaxResponse ) { item = document.createElement( 'li' ); item.appendChild( document.createTextNode( ajaxResponse[ i ].name ) ); documentFragment.appendChild( item ); } //将documentFragment加到list中 list.appendChild( documentFragment );}John Resig有一篇很棒的 博客 详细解释了DocumentFragment以及它对性能的影响.
使用innerHTML操作DOM (DOM Manipulation using innerHTML)
永远不要对innerHTML使用+=来添加新的标签.无论什么时候修改innerHTML,DOM都会被更新(浏览器需要重新绘制).所以使用+=操作符添加新的标签也会降低性能,在循环里使用将更为严重.
var container = document.getElementById( 'container' ); for( var i = 1; i <= 10; ++i ) { container.innerHTML += 'Item ' + i + '<br />';}
可以使用一个临时变量来存储要添加的内容. 下面是一个例子:
var container = document.getElementById( 'container' ) , str = ''; for( var i = 1; i <= 10; ++i ) { str += 'Item ' + i + '<br />';} container.innerHTML += str;
转载请注明出处:http://blog.csdn.net/horkychen
原文地址:http://www.ifadey.com/2011/05/javascript-mistakes-you-must-avoid/
Reference:你可能会犯的11个JavaScript错误