错误剖析之JavaScript的9个陷阱及评点_javascript技巧

来自Nine Javascript Gotchas, 以下是JavaScript容易犯错的九个陷阱。虽然不是什么很高深的技术问题,但注意一下,会使您的编程轻松些,即所谓make life easier. 笔者对某些陷阱会混杂一些评点。

1、最后一个逗号
如这段代码,注意最后一个逗号,按语言学角度来说应该是不错的(python的类似数据类型辞典dictionary就允许如此)。IE会报语法错误,但语焉不详,你只能用人眼从几千行代码中扫描。

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

2、this的引用会改变
如这段代码:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

并不如你所愿,答案并不是”JavaScript rules”。在执行MyObject.ClickHandler时,代码中红色这行,this的引用实际上指向的是document.getElementById("theText")的引用。可以这么解决:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

实质上,这就是JavaScript作用域的问题。如果你看过,你会发现解决方案不止一种。

3、标识盗贼
在JavaScript中不要使用跟HTML的id一样的变量名。如下代码:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

IE会报对象未定义的错误。我只能说:IE sucks.

4、字符串只替换第一个匹配
如下代码:

[Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

而实际上,结果是”This_is a title“. 在JavaScript中,String.replace的第一个参数应该是正则表达式。所以,正确的做法是这样:

var fileName = "This is a title".replace(/ /g,"_");

5、mouseout有时意味着mousein
事实上,这是由于事件冒泡导致的。IE中有mouseenter和mouseleave,但不是标准的。作者在此建议大家使用库比如YUI来解决问题。

6、parseInt是基于进制体系的
这个是常识,可是很多人给忽略了parseInt还有第二个参数,用以指明进制。比如,parseInt("09"),如果你认为答案是9,那就错了。因为,在此,字符串以0开头,parseInt以八进制来处理它,在八进制中,09是非法,返回false,布尔值false转化成数值就是0. 因此,正确的做法是parseInt("09", 10). 

7、for...in...会遍历所有的东西
有一段这样的代码:

var arr = [5,10,15]
var total = 1;
for ( var x in arr) {
   total = total * arr[x];
}

运行得好好的,不是吗?但是有一天它不干了,给我返回的值变成了NaN, 晕。我只不过引入了一个库而已啊。原来是这个库改写了Array的prototype,这样,我们的arr平白无过多出了一个属性(方法),而for...in...会把它给遍历出来。所以这样做才是比较安全的:

for ( var x = 0; x < arr.length; x++) {
   total = total * arr[x];
}

其实,这也是污染基本类的prototype会带来危害的一个例证。

8、事件处理器的陷阱
这其实只会存在使用作为对象属性的事件处理器才会存在的问题。比如window.onclick = MyOnClickMethod这样的代码,这会复写掉之前的window.onclick事件,还可能导致IE的内容泄露(sucks again)。在IE还没有支持DOM 2的事件注册之前,作者建议使用库来解决问题,比如使用YUI:

YAHOO.util.Event.addListener(window, "click", MyOnClickMethod);

这应该也属于常识问题,但新手可能容易犯错。

9、Focus Pocus
新建一个input文本元素,然后把焦点挪到它上面,按理说,这样的代码应该很自然:

var newInput = document.createElement("input");
document.body.appendChild(newInput);
newInput.focus();
newInput.select();

但是IE会报错(sucks again and again)。理由可能是当你执行focus()的时候,元素还不存在。因此,我们可以延迟执行:

var newInput = document.createElement("input");
newInput.id = "TheNewInput";
document.body.appendChild(newInput);
setTimeout(function(){ //这里我使用闭包改写过,若有兴趣可以对比原文
 document.getElementById('TheNewInput').focus();
 document.getElementById('TheNewInput').select();}, 10);

在实践中,JavaScript的陷阱还有很多很多,大多是由于解析器的实现不到位而引起。这些东西一般都不会在教科书中出现,只能靠开发者之间的经验分享。谢天谢地,我们生活在网络时代,很多碰到的问题,一般都可以在Google中找到答案。

时间: 2024-12-06 10:46:08

错误剖析之JavaScript的9个陷阱及评点_javascript技巧的相关文章

JavaScript执行效率与性能提升方案_javascript技巧

如何提升JavaScript执行效率与性能在前端开发中位于一个很重要的地方,这节来研究下如何在平时做项目过程中,提升JavaScript性能与运行效率. 循环 循环是很常用的一个控制结构,大部分东西要依靠它来完成,在JavaScript中,我们可以使用for(;;),while(),for(in)三种循环,事实上,这三种循环中for(in)的效率极差,因为他需要查询散列键,只要可以就应该尽量少用.for(;;)和while循环的性能应该说基本(平时使用时)等价. 而事实上,如何使用这两个循环,则

javascript判断firebug是否开启的方法_javascript技巧

本文实例讲述了javascript判断firebug是否开启的方法.分享给大家供大家参考,具体如下: 经常用Firefox + Firebug调试JavaScript的朋友都知道,一但开启firebug,页面js的运行将显著变慢. 页面的javascript是否能够主动判断当前Firebug是否已开启呢? 答案是肯定的. Firebug已经更新了很多个版本了.印象中某个旧版本可以通过检测console.firebug来判断,不过现在已经无效了. 最近几个版本的firebug可以通过console

Javascript基础知识盲点总结之函数_javascript技巧

函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.本文重点给大家介绍js基础知识盲点总结之函数. 一.函数中的arguments对象 每个函数内部都有一个arguments,它能返回函数所接受的所有参数 注意:argumens接收的是实参 如下是利一个利用arguments特性编写的求和函数: function sumOnSteroids(){ var I, res = 0; var number_of_params = arguments.length; for(I = 0; I <

javascript弹性运动效果简单实现方法_javascript技巧

本文实例讲述了javascript弹性运动效果简单实现方法.分享给大家供大家参考,具体如下: 弹性运动实现原理:加速运动+减速运动+摩擦运动 运行效果截图如下: 实例代码如下: <!doctype html> <html> <head> <meta charset="utf-8"> <title>无标题文档</title> <style> #div1{ width:100px; height:100px

javascript合并表格单元格实例代码_javascript技巧

本文为大家介绍了一段来源于网络上的代码实例,能够合并单元格,下面和大家分享一下,希望能够给需要的朋友或多或少带来一定的帮助. 代码实例如下: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"/> <title>表格单元格合并代码</title> <script type="text/javascript"> function au

javascript随机显示背景图片的方法_javascript技巧

本文实例讲述了javascript随机显示背景图片的方法.分享给大家供大家参考.具体如下: 将以下代码加入HTML的<head></head>之间: <script LANGUAGE="JavaScript"> bg = new Array(2); //设定图片数量,如果图片数为3,这个参数就设为2,依次类推 bg[0] = 'bg1.gif' //显示的图片路径,可用http:// bg[1] = 'bg2.gif' bg[2] = 'bg3.gi

JavaScript的9个陷阱及评点分析_javascript技巧

1. 最后一个逗号 如这段代码,注意最后一个逗号,按语言学角度来说应该是不错的(python的类似数据类型辞典dictionary就允许如此).IE会报语法错误,但语焉不详,你只能用人眼从几千行代码中扫描. <script>   var theObj = {         city : "Boston",         state : "MA",   } </script>  2. this的引用会改变 如这段代码: <input 

深入剖析javascript中的exec与match方法_javascript技巧

exec是正则表达式的方法,而不是字符串的方法,它的参数才是字符串,如下所示: var re=new RegExp(/\d/); re.exec( "abc4def" ); //或者使用perl风格: /\d/.exec( "abc4def" ); //match才是字符串类提供的方法,它的参数是正则表达式对象,如下用法是正确的: "abc4def".match(\d); exec和match返回的都是数组 如果执行exec方法的正则表达式没有分

9个让JavaScript调试更简单的Console命令_javascript技巧

一.显示信息的命令 <!DOCTYPE html> <html> <head> <title>常用console命令</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> </head> <body> <script type="text/javascri