- 浏览: 56908 次
- 性别:
- 来自: 安徽
文章分类
最新评论
-
nhm_lxy:
ViolateRecordDto dto=new Viola ...
j2ee Struts2.0 下的文件上传一些东西
在IE6中有“缺少标识符、字符串或数字”的错误。
多余的逗号
在任何JavaScript对象定义中,最后一个属性决不能以一个逗号结尾。Firefox不会出错,而IE会报语法错误。
var theObj = {
city : "Boston",
state : "MA",//注意 这个逗号在ie6 中 会报错 在ff,谷歌浏览器ok
}
由于ie6 没有debug 功能 ,因此 花了较多时间 ,所以要记下来!网上也有其他遇到这样的问题,解决方法和这差不多!
下面的文章是转载的,感觉蛮实用的!
blog网址:http://dancewithnet.com/2008/10/27/javascript-gotchas/
这本来是翻译Estelle Weyl的《15 JavaScript Gotchas》,里面介绍的都是在JavaScript编程实践中平时容易出错或需要注意的地方,并提供避开这些陷阱的方法,总体上讲,就是在认清事物本质的基础样要坚持好的编程习惯,其实这就是Douglas Crockford很久以前提出的JavaScript风格要素问题了,有些内容直接是相同的,具体请看《Javascript风格要素》。在翻译的过程中,我又看到了贤安去年翻译的《JavaScript的9个陷阱及评点》,其内容又有些交叉在一起,所以我就在现有翻译的基础上做了一个简单的拼合,并依据自己的理解增加了一些注释和解释。
- 区分大小写:变量名、属性和方法全部都区分大小写
- 不匹配的引号、圆括号或花括号将抛出错误
- 条件语句:3个常见陷阱
- 换行:一直用分号结束语句来避免常见的换行问题
- 标点法:在对象声明的尾部逗号将导致出错
- HTML id 冲突
- 变量作用域:全局变量对局部变量
- 函数重载:当重载不存在时,覆盖函数
- 区分string.replace()函数不是全局的
- parseInt应该包含两个参数
- “this”和绑定问题
- 为参数设置默认值,以免你遗漏它们
- for each循环是用于对象而不是数组
- switch语句需要点技巧
- 总是在检查undefined前检查null
- 时间处理陷阱
区分大小写
变量名和函数名都是区分大小写的。就像配错的引号一样,这些大家都知道。但是,由于错误是不作声的,所以这是一个提醒。为自己选择一个命名规则,并坚持它。而且,记住JavaScript中的原生函数和CSS属性都是骆驼拼写法(camelCase)。
getElementById(’myId’) != getElementByID(’myId’); //它应该是“Id”而不是“ID”
getElementById(’myId‘) != getElementById(’myID‘); // “Id”也不等于“ID”
document.getElementById('myId').style.Color; //返回 "undefined"
不匹配的引号、圆括号或花括号
避免陷入不匹配的引号、圆括号或花括号陷阱的最好方式是编码时一直同时写出打开和关闭这两个元素符号,然后在其中间加入代码。开始:
var myString = ""; //在输入字符串值之前写入这对引号
function myFunction(){
if(){//关闭每个打开的括弧
}
}
//统计所有的左括号和右括号数量,并且确保它们相等
alert(parseInt(var1)*(parseInt(var2)+parseInt(var3))); //关闭每个打开的圆括号
每当你打开一个元素,请关闭它。当你添加了关闭圆括号后,你再把函数的参数放进圆括号中。如果有一串圆括号,统计所有打开的圆括号和所有关闭的圆括号,并且确保这两个数字相等。
条件语句(3个陷阱)
-
所有的条件语句都必须位于圆括号中。执行语句主体不管是一句还是多句都强烈建议用花括号包围起来,这样能避免很多因修改或嵌套而产生的潜在错误。
if(var1 == var2){//statement}
-
不要犯无意地使用赋值运算符的错误:把第二个参数的值赋给第一个参数。因为它是一个逻辑问题,它将一直返回true且不会报错。
if(var1 = var2){} // 返回true。把var2赋值给var1
-
JavaScript是弱类型,除了在switch语句中。当JavaScript在case比较时,它是非弱类型。
<!--[if !supportLists]-->4. <!--[endif]-->var myVar = 5;
<!--[if !supportLists]-->5. <!--[endif]-->if(myVar == '5'){ //返回true,因为JavaScript是弱类型
<!--[if !supportLists]-->6. <!--[endif]-->alert("hi"); //这个alert将执行,因为JavaScript通常不在意数据类型
<!--[if !supportLists]-->7. <!--[endif]-->}
<!--[if !supportLists]-->8. <!--[endif]-->switch(myVar){
<!--[if !supportLists]-->9. <!--[endif]-->case '5':
<!--[if !supportLists]-->10. <!--[endif]-->alert("hi"); //这个alert将不会执行,因为数据类型不匹配
<!--[if !supportLists]-->11. <!--[endif]-->}
换行
当心JavaScript中的硬换行。换行被解释为表示行结束的分号。即使在字符串中,如果在引号中包括了一个硬换行,那么你会得到一个解析错误(未结束的字符串)。
var bad = '<ul id="myId">
<li>some text</li>
<li>more text</li>
</ul>'; // 未结束的字符串错误
var good = '<ul id="myId">' +
‘<li>some text</li>‘ +
‘<li>more text</li>‘ +
‘</ul>’; // 正确
前面讨论过的换行被解释为分号的规则并不适用于控制结构这种情况:条件语句关闭圆括号后的换行并不是给其一个分号。
一直使用分号和圆括号,那么你不会因换行而出错,你的代码易于阅读,且除了那些不使用分号的怪异源码外你会少一些顾虑:所以当移动代码且最终导致两个语句在一行时,你无需担心第一个语句是否正确结束。
多余的逗号
在任何JavaScript对象定义中,最后一个属性决不能以一个逗号结尾。Firefox不会出错,而IE会报语法错误。
var theObj = {
city : "Boston",
state : "MA",//IE6和IE7中有“缺少标识符、字符串或数字”的错误,IE8 beta2修正了它
}
HTML id 冲突
JavaScript DOM绑定(JavaScript DOM bindings)允许通过HTML id索引。在JavaScript中函数和属性共享同一个名字空间。所以,当在HTML中的一个id和函数或属性有相同的名字时,你会得到难以跟踪的逻辑错误。然而这更多是一个CSS最佳实践的问题,当你不能解决你的JavaScript问题时,想起它是很重要的。
<ul>
<li id="length">1</li>
<li id="thisLength">2</li>
<li id="thatLength">3</li>
</ul>
<script>
var listitems = document.getElementsByTagName('li');
var liCount = listitems.length; //IE下返回的是<li id="length">1</li>这个节点而不是所有<li的数量
var thisLength = document.getElementById('thisLength');
thatLength = document.getElementById('thatLength');
//IE下会出现“对象不支持此属性和方法”的错误,IE8 beta2下首次加载页面会出错,刷新页面则不会
//在IE中thisLength和thatLength直接表示以其为id值的DOM节点,
//所以赋值时会出错,当有var声明时,IE会把其当着变量,这个时候就正常了。
</script>
如果你要标记(X)HTML,绝不要使用JavaScript方法或属性名作为id的值。并且,当你写JavaScript时,避免使用 (X)HTML中的id值作为变量名。
变量作用域
JavaScript中的许多问题都来自于变量作用域:要么认为局部变量是全局的,要么用函数中的局部变量覆盖了全局变量。为了避免这些问题,最佳方案是根本没有任何全局变量。但是,如果你有一堆,那么你应该知道这些陷阱。
不用var关键字声明的变量是全局的。记住使用var关键字声明变量,防止变量具有全局作用域。在下面例子中,在函数中声明的变量具有全局变量,因为没有使用var关键字声明:
anonymousFuntion1 = function(){
globalvar = 'global scope'; //全局声明,因为“var”遗漏了
return localvar;
}();
alert(globalvar); //弹出“global scope”,因为函数中的变量是全局声明
anonymousFuntion2 = function(){
var localvar = 'local scope'; //使用“var”局部声明
return localvar;
}();
alert(localvar); //错误 “localvar未定义”。没有全局定义localvar
作为参数引进到函数的变量名是局部的。如果参数名也是一个全局变量的名字,像参数变量一样有局部作用域,这没有冲突。如果你想在函数中改变一个全局变量,这个函数有一个参数复制于这个全局变量名,记住所有全局变脸都是window对象的属性。
var myscope = "global";
function showScope(myscope){
return myscope; //局部作用域,即使有一个相同名字的全局变量
}
alert(showScope('local'));
function globalScope(myscope){
myscope = window.myscope; //全局作用域
return myscope;
}
alert(globalScope(’local’));
你甚至可以在循环中声明变量:
for(var i = 0; i < myarray.length; i++){}
覆盖函数/重载函数
当你不止一次的声明一个函数时,这个函数的最后一次声明将覆盖掉该函数的所有前面版本且不会抛出任何错误或警告。这不同于其他的编程语言,像Java,你能用相同的名字有多重函数,只要它们有不同的参数:调用函数重载。在JavaScript中没有重载。这使得不能在代码中使用JavaScript核心部分的名字极其重要。也要当心包含的多个JavaScript文件,像一个包含的脚本文件可能覆盖另一个脚本文件中的函数。请使用匿名函数和名字空间。
(function(){
// creation of my namespace 创建我的名字空间
if(!window.MYNAMESPACE) {
window['MYNAMESPACE'] = {};
}
//如果名字空间不存在,就创建它
//这个函数仅能在匿名函数中访问
function myFunction(var1, var2){
//内部的函数代码在这儿
}
// 把内部函数连接到名字空间上,使它通过使用名字空间能访问匿名函数的外面
window['MYNAMESPACE']['myFunction'] = myFunction;
})(); // 圆括号 = 立即执行
// 包含所有代码的圆括号使函数匿名
这个例子正式为了实现解决上一个陷阱“变量作用域”的最佳方案。匿名函数详细内容请看《Javascript的匿名函数》。YUI整个库只有YAHOO和YAHOO_config两个全局变量,它正是大量应用匿名函数和命名空间的方法来实现,具体请看《Javascript的一种模块模式》。
字符串替换
一个常见错误是假设字符串替换方法的行为会对所有可能匹配都产生影响。实际上,JavaScript字符串替换只改变了第一次发生的地方。为了替换所有发生的地方,你需要设置全局标识。同时需要记住String.replace()的第一个参数是一个正则表达式。
var myString = "this is my string";
myString = myString.replace("","%20"); // "this%20is my string"
myString = myString.replace(/ /,"%20"); // "this%20is my string"
myString = myString.replace(/ /g,"%20"); // "this%20is%20my%20string"
parseInt
在JavaScript得到整数的最常见错误是假设parseInt返回的整数是基于10进制的。别忘记第二个参数基数,它能是从2到36之间的任何值。为了确保你不会弄错,请一直包含第二个参数。
parseInt('<chsdate year="2009" month="10" day="8" islunardate="False" isrocdate="False" w:st="on">09/10/08</chsdate>'); //0
parseInt(’<chsdate year="2009" month="10" day="8" islunardate="False" isrocdate="False" w:st="on">09/10/08</chsdate>′,10); //9, 它最可能是你想从一个日期中得到的值
如果parseInt没有提供第二个参数,则前缀为 ‘0x’ 的字符串被当作十六进制,前缀为 ‘0′ 的字符串被当作八进制。所有其它字符串都被当作是十进制的。如果 numString 的前缀不能解释为整数,则返回 NaN(而不是数字)。
‘this’
另一个常见的错误是忘记使用“this”。在JavaScript对象中定义的函数访问这个对象的属性,但没有使用引用标识符“this”。例如,下面是错误的:
function myFunction() {
var myObject = {
objProperty: "some text",
objMethod: function() {
alert(objProperty);
}
};
myObject.objMethod();
}
function myFunction() {
var myObject = {
objProperty: "some text",
objMethod: function() {
alert(this.objProperty);
}
};
myObject.objMethod();
}
有一篇A List Apart文章用通俗易懂的英文表达了this绑定的问题。
对this使用最大的陷阱是this在使用过程中其引用会发生改变:
<input type="button" value="Gotcha!" id="MyButton">
<script>
var MyObject = function () {
this.alertMessage = "Javascript rules";
this.ClickHandler = function() {
alert(this.alertMessage );
//返回结果不是”JavaScript rules”,执行MyObject.ClickHandler时,
//this的引用实际上指向的是document.getElementById("theText")的引用
}
}();
document.getElementById(”theText”).onclick = MyObject.ClickHandler
</script>
其解决方案是:
var MyObject = function () {
var self = this;
this.alertMessage = “Javascript rules”;
this.OnClick = function() {
alert(self.value);
}
}();
类似问题的更多细节和解决方案请看《JavaScript作用域的问题》。
遗漏的参数
当给函数增加一个参数时,一个常见的错误是忘记更新这个函数的所有调用。如果你需要在已经被调用的函数中增加一个参数来处理一个特殊情况下的调用,请给这个函数中的这个参数设置默认值,以防万一在众多脚本中的众多调用中的一个忘记更新。
function addressFunction(address, city, state, country){
country = country || “US”; //如果没有传入country,假设 “US”
span>//剩下代码
}
你也能通过获取arguments来解决。但是在这篇文章我们的注意力在陷阱上。同时在《Javascript风格要素(2)》也介绍了||巧妙应用。
for关键字
在JavaScript中关键字for有两种使用方式,一个是for语句,一个是for/in语句。for/in语句将遍历所有的对象属性(attribute),包括方法和属性(property)。决不能使用for/in来遍历数组:仅在当需要遍历对象属性和方法时才使用for/in。
-
for(var myVar in myObject)语句用一个指定变量无任何规律地遍历对象的所有属性。如果for/in循环的主体删除了一个还没有枚举出的属性,那么该属性就不在枚举。如果循环主体定义了新属性,那么循环是否枚举该属性则是由JavaScript的实现决定。
-
for(var 1=0; i < myArray.length; i++)语句会遍历完一个数组的所有元素。
为了解决这个问题,大体上你可以对对象使用 for … in,对数组使用for循环:
listItems = document.getElementsByTagName('li');
for (var listitem in listItems){
//这里将遍历这个对象的所有属性和方法,包括原生的方法和属性,但不遍历这个数组:出错了!
}
//因为你要循环的是数组对象,所用for循环
for ( var i = 0; i < listItems.length; i++) {
//这是真正你想要的
}
对象的有些属性以相同的方式标记成只读的、永久的或不可列举的,这些属性for/in无法枚举。实际上,for/in循环
会遍历所有对象的所有可能属性,包括函数和原型中的属性。所有修改原型属性可能对for/in循环带来致命的危害,所以需要采用hasOwnProperty和typeof做一些必要的过滤,最好是用for来代替for/in。
switch语句
Estelle Weyl写了一篇switch statement quirks,其要点是:
-
没有数据类型转换
-
一个匹配,所有的表达式都将执行直到后面的break或return语句执行
-
你可以对一个单独语句块使用多个case从句
undefined ≠ null
null是一个对象,undefined是一个属性、方法或变量。存在null是因为对象被定义。如果对象没有被定义,而测试它是否是null,但因为没有被定义,它无法测试到,而且会抛出错误。
if(myObject !== null && typeof(myObject) !== 'undefined') {
//如果myObject是undefined,它不能测试是否为null,而且还会抛出错误
}
if(typeof(myObject) !== 'undefined' && myObject !== null) {
//处理myObject的代码
}
Harish Mallipeddi对undefined和null有一个说明。
事件处理陷阱
刚接触事件处理时最常见的写法就是类似:
window.onclick = MyOnClickMethod
这种做法不仅非常容易出现后面的window.onclick事件覆盖掉前面的事件,还可能导致大名顶顶的IE内存泄露问题。为了解决类似问题,4年前Simon Willison就写出了很流行的addLoadEvent():
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
}else {
window.onload = function() {
oldonload();
unc();
}
}
}
addEvent(window,'load',func1,false);
addEvent(window,'load',func2,false);
addEvent(window,'load',func3,false);
当然在JavaScript库盛行的现在,使用封装好的事件处理机制是一个很好的选择,比如在YUI中就可以这样写:
YAHOO.util.Event.addListener(window, "click", MyOnClickMethod)
发表评论
-
关于JavaScript parseInt() 函数
2010-04-10 15:39 621在做了在线编程的一题,错了以后发现对与这个函数的基本知识缺乏: ... -
注册页面 FormValidator插件 使用
2010-07-23 11:44 1148最近修改注册页面 尝试使用了JQuery的一个插件 Form ... -
JAVASCRIPT弹出窗口大总结 (转)
2010-07-28 15:23 758JAVASCRIPT弹出窗口大总结 2008-08-29 1 ... -
javascript:void(0)与# 我所遇到了问题
2010-10-10 16:38 1804刚好把项目的大体完善了。现在回想一下之前我所遇到的一些细节问题 ... -
关于js中常用的return false使用
2010-10-10 16:54 3441return false以前没有怎么关注过,最近遇到关于这个问 ... -
JQuery 的select处理 (琐碎)
2010-11-14 16:05 1334今天因为需求 需要改动一些页面显示,其中之一是修改积分政策发布 ... -
Js控制 form 提交到不同的action
2010-12-01 11:28 1957js控制form提交到不同action 我的环境是ssh ... -
国外 Ajax 和 Jquery 网站推荐(转)
2010-12-22 21:15 987经常逛这些国外的网站,看到很不错的控件和J ... -
转 iframe 子 父类窗口操作
2011-01-20 10:04 1220一、Iframe篇 原博客网址:http:// ... -
CSS中display:inline | block |inline-block的详解区别(转)
2011-02-14 21:24 1167display:block就是将元素显示为块级元素. blo ...
相关推荐
这个场景中提到的"js导出Excel和Word,不支持ie",指的是使用JavaScript在HTML页面前端实现Excel和Word文件的生成,但需要注意的是,这种方法可能不适用于已经过时的Internet Explorer浏览器。 1. **JavaScript导出...
用于兼容IE浏览器使用RSA加密的工具类,直接引入,并且使用new ecrypt()即可使用,官网的js会倒是IE浏览器报错SCRIPT1010错误,原因为逗号(,)关键字(default,delete)等。
首先,IE6之所以需要特别关注,是因为它与其他浏览器在很多细节实现上存在较大差异,尤其是在对JavaScript的原生支持上。这导致很多新兴的Web技术在IE6上无法使用或者需要特定的兼容代码。因此,快速准确地判断...
在用ExtJS做前端开发的时候,发现系统可以在谷歌浏览器、火狐下正常显示,但是用IE浏览器打开就会报错,报错信息如:Expected identified, string or number。后来,检查的代码的时候发现,是由于js代码中逗号用的不...
在描述中提到的问题是当JSON对象的最后一个键值对后面多了一个逗号时,IE6和IE7会抛出“缺少标识符、字符串或数字”的错误。这是因为这些老版本的IE浏览器并不完全遵循JSON标准,而标准规定JSON对象或数组的最后不...
这种技巧展示了JavaScript的灵活性和创造力,同时提醒我们在处理浏览器兼容性问题时,需要深入理解不同浏览器的差异和JS的内部工作原理。虽然现代浏览器已经大大减少了这些差异,但了解这些历史遗留问题有助于我们更...
在JavaScript中解决IE6下的PNG透明问题是一个常见的挑战,因为IE6不支持PNG-24格式的透明特性。这个问题可以通过引入特定的JavaScript库或者使用一些技巧来解决。在这个实例中,我们将探讨如何利用JavaScript和一个...
在此之前,如IE6、IE7等旧版本浏览器会在语法分析阶段就报错,阻止代码执行,而Firefox、Chrome、Safari等浏览器则可以忽略尾部的逗号,正常执行代码。 例如,在定义对象时: ```javascript var obj = {name: "Jack...
9. **兼容性问题**: 需要注意的是,这种方案主要针对IE浏览器,其他现代浏览器如Chrome、Firefox可能需要不同的实现方式,例如使用`download`属性或`FileSaver.js`库。 10. **安全与隐私**: 使用这种方式导出数据...
在IE6和Chrome等浏览器中,JSON对象的原生支持可能不一致。为了实现跨浏览器的JSON处理,我们可以使用原生JavaScript方法。在提供的代码中,作者定义了一个名为`toJSON`的函数,用于实现JSON序列化。 这个`toJSON`...
在IT行业中,JavaScript(简称JS)作为一种广泛应用于前端开发的脚本语言,常常需要处理用户在浏览器中的输入问题。在移动设备或者某些特殊场景下,由于硬件限制或安全考虑,可能无法直接调用系统软键盘,这时就需要...
在过去的Web开发中,由于Internet Explorer(IE)浏览器对某些标准的不完全支持,开发者常常需要编写特定的代码来处理IE特有的问题。这篇内容主要讨论的是如何用最简洁的代码来判断浏览器是否为IE。 在JavaScript中...
在不同浏览器环境下实现这一功能时,由于各浏览器对JavaScript的支持程度和API的不同,需要采取不同的策略。针对“ie、360、火狐等浏览器用js导出Excel”的需求,我们可以探讨一下相关的JavaScript技术以及处理不同...
IE6浏览器由于其内核的限制,对于PNG图片的透明度处理一直存在问题,特别是在背景图片或者带有透明度的PNG图片上,这些图片在IE6中会显示出非预期的效果,常见的问题包括透明区域显示为灰色的背景色或者图片的透明...
- 它允许用户在IE6、7、8等旧版IE浏览器中使用更现代的网络标准,提高网页渲染效率和兼容性。 - 安装了GCF后,即使IE的外观没有变化,其背后使用的是Chrome的内核,从而提升了网页的用户体验。 以上知识点围绕着...
由于工作中web开发经常遇到兼容性的问题 基本都是各类浏览器(特别是IE各版本)对JS中组件 对象的不支持导致 而有一部分又是开发人员在编写的时候代码不规范(这种场景经常发生在拷贝复制的时候)导致 如数组中的...
总之,调试Vue在IE10下出现空白页的问题,需要深入理解JavaScript的兼容性问题,并熟练运用调试技巧。一旦找到问题源头,修复它并确保代码在不同浏览器下都能正常运行。在开发过程中,保持对浏览器兼容性的关注,...
尝试过N多方法,最后发现导致出现这种问题的原因(90%以上的可能性)是js的数组中多了一个英文的逗号’,’,而这种在chrome和火狐中是没有问题的,如下面的代码所示: 代码如下: var win = Ext.create(‘Ext.window....