JavaScript的陷阱(3)
作者:秦歌 来源:随网之舞 发布时间:2008-10-28 19:52:00
‘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 ); }}();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”; 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 ( 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') { }if(typeof(myObject) !== 'undefined' && myObject !== null) { }
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);


猜你喜欢
- 本文实例讲述了JS仿iGoogle自定义首页模块拖拽特效的方法。分享给大家供大家参考。具体实现方法如下:<!DOCTYPE html
- 本文实例代码主要实现python编程测试电脑开启最大线程数,具体实现代码如下。#!/usr/bin/env python #co
- mapmap(funcname, list)python的map 函数使得函数能直接以list的每个元素作为参数传递到funcname中,
- 本文实例讲述了MySQL 多表关联一对多查询实现取最新一条数据的方法。分享给大家供大家参考,具体如下:MySQL 多表关联一对多查询取最新的
- 公司服务器上的ip最少的也有100多个,有时候查到一个站的Ip, 不想通过OA去查,自己就用自己最近学的python知识,结合数据库,编写了
- 整理了一些JS的常用方法,包括验证啊,全选反选啊,ajax请求啊之类的,因为就是自己用的,写的都比较简单,就算抛砖引玉吧,喜欢的就拿去,不喜
- 前言:线程是指进程内的一个执行单元,也是进程内的可调度实体.与进程的区别:(1) 地址空间:进程内的一个执行单元;进程至少有一个线程;它们共
- 本文实例讲述了php+mysqli使用面向对象方式更新数据库的方法,分享给大家供大家参考。具体实现方法如下:<?php//第一步:创建
- 此文主要讲述的是SQL Server连接中经常出现的3个常见错误,以及对这三个错误的详细分析,如果你其心存好奇的话,以下的文章将会揭开它的神
- 这篇文章主要介绍了python cv2在验证码识别中应用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值
- 首先呢,需要有两个mysql服务器。如果做测试的话可以在同一台机器上装两个mysql服务程序,注意要两个运行程序的端口不能一样。我用的是一个
- 启发式搜索在人工智能中起着关键作用。在本章中,您将详细了解它。AI中的启发式搜索的概念启发式是一个经验法则,它引导我们找到可能的解决方案。人
- 突然想到一个视频里面弹幕被和谐的一满屏的*号觉得很有趣,然后就想用python来试试写写看,结果还真玩出了点效果,思路是首先你得有一个脏话存
- 1、视图函数之前的文章说过,在 Flask 中路由是请求的 url 与处理函数之间的映射,使用app.route装饰器将处理函数和 url
- 内连接(inner join)。 外连接: 全连接(full join)、左连接(left join)、右连接(right join)。 交
- 01 实现背景1、PHPdict.txt,一个文本文件,包含可能的敏感目录后缀2、HackRequests模块,安全测试人员专用的类Requ
- mysql使用left join连接出现重复问题描述在使用连接查询的时候,例如以A表为主表,左连接B表,我们期望的是A表有多少条记录,查询结
- '-----------------------------------------------------------
- 我就废话不多说了,大家还是直接看代码吧~//isSymbol表示有无符号func BytesToInt(b []byte, isSymbol
- 介绍使用subprocess模块的目的是用于替换os.system等一些旧的模块和方法。运行python的时候,我们都是在创建并运行一个进程