开发者最容易犯的13个JavaScript错误

开发者最容易犯的JavaScript错误,总结出13个。这些当中可能少不了你犯的错误。我们描述了这些陋习,并列出来解决办法,希望对开发者有帮助。

1.for...数组迭代的用法 Usage of for..in to iterate Arrays

举例:

  1. var myArray = [ “a”, “b”, “c” ];   
  2. var totalElements = myArray.length;   
  3. for (var i = 0; i < totalElements; i++) {   
  4. console.log(myArray[i]);   
  5. }   

这里主要的问题是语句中的“for..."不能保证顺序,这意味着你将获得不同的执行结果。此外,如果有人增加一些其他自定义功能的函数Array.prototype,你的循环将重复遍历这些函数,就像原数组项。

解决办法:一直使用规则的for循环来遍历数组。

  1. var myArray = [ “a”, “b”, “c” ];   
  2. for (var i=0; i<myArray.length; i++) {   
  3. console.log(myArray[i]);   
  4. }   

2.数组维度Array dimensions

举例

  1. var myArray = new Array(10);  

第二个问题是开发者使用数组构成器来创建数组,技术上是正确的,然而会比文字符号(literal notation)慢解决办法:使用文字符号来初始化数组,不要预定义数组长度。

  1. var myArray = []; 

3.未定义属性 Undefined properties

举例:

  1. var myObject = {   
  2.     someProperty: “value”,   
  3.     someOtherProperty: undefined   
  4. }  

未定义属性,将在对象中创建元素(键‘someOtherProperty’和值‘undefined’.)。如果你遍历数组,检测已存在的元素,那么下面的语句将都返回“未定义/undefined”

  1. typeof myObject['someOtherProperty'// undefined   
  2.   
  3. typeof myObject['unknownProperty'// undefined   

解决办法:如果你想明确声明对象中的未初始化的属性,标记它们为Null(空)。

  1. var myObject = {   
  2. someProperty: “value”,   
  3. someOtherProperty: null   
  4. }  

4.闭包的滥用Misuse of Closures

举例:

  1. function(a, b, c) {   
  2. var d = 10;   
  3. var element = document.getElementById(‘myID’);   
  4. element.onclick = (function(a, b, c, d) {   
  5. return function() {   
  6. alert (a + b + c + d);   
  7. }   
  8. })(a, b, c, d);   
  9. }   

这里开发者使用两个函数来传递参数a、b、c到onclick handler。双函数根本不需要,徒增代码的复杂性。

变量abc已经在局部函数中被定义,因为他们已经在主函数中作为参数被声明。局部函数中的任何函数都可创建主函数中定义的所有变量的闭包。因此不需要再次传递它们。

看看这里JavaScript Closures FAQ了解更多。

解决办法:使用闭环来简化你的代码。

  1. function (a, b, c) {   
  2. var d = 10;   
  3. var element = document.getElementById(‘myID’);   
  4. element.onclick = function() {   
  5. //a, b, and c come from the outer function arguments.   
  6. //d come from the outer function variable declarations.   
  7. //and all of them are in my closure   
  8. alert (a + b + c + d);   
  9. };   
  10. }   

5.循环中的闭包Closures in loops

举例:

  1. var elements = document.getElementByTagName(‘div’);   
  2. for (var i = 0; i<elements.length; i++) {   
  3. elements[i].onclick = function() {   
  4. alert(“Div number “ + i);   
  5. }   
  6. }   

在这里例子里面,当用户点击不同的divs时,我们想触发一个动作(显示“Div number 1”, “Div number 2”… 等) 。然而,如果你在页面有10个divs,他们全部都会显示“Div number 10”。

问题是当我们使用局部函数创建一个闭包时,函数中的代码可以访问变量i。关键是函数内部i和函数外部i涉及同样的变量。当我们的循环结束,i指向了值10,所以局部函数中的i的值将是10。

解决办法:使用第二函数来传递正确的值。

  1. var elements = document.getElementsByTagName(‘div’);   
  2. for (var i = 0; i<elements.length; i++) {   
  3. elements[i].onclick = (function(idx) { //Outer function   
  4. return function() { //Inner function   
  5. alert(“Div number “ + idx);   
  6. }   
  7. })(i);   
  8. }   

6.DOM对象的内测泄漏Memory leaks with DOM objects

举例:

  1. function attachEvents() {   
  2. var element = document.getElementById(‘myID’);   
  3. element.onclick = function() {   
  4. alert(“Element clicked”);   
  5. }   
  6. };   
  7. attachEvents();   

该代码创建了一个引用循环。变量元素包含函数的引用(归于onclick属性)。同时,函数保持一个DOM元素的引用(提示函数内部可以访问元素, 因为闭包。)。所以JavaScript垃圾收集器不能清除元素或是函数,因为他们被相互引用。大部分的JavaScript引擎对于清除循环应用都不够 聪明。

解决办法:避免那些闭包,或者不去做函数内的循环引用。

  1. function attachEvents() {   
  2. var element = document.getElementById(‘myID’);   
  3. element.onclick = function() {   
  4. //Remove element, so function can be collected by GC   
  5. delete element;   
  6. alert(“Element clicked”);   
  7. }   
  8. };   
  9. attachEvents(); 

7.区别整数数字和浮点数字Differentiate float numbers from integer numbers

举例:

  1. var myNumber = 3.5;   
  2. var myResult = 3.5 + 1.0; //We use .0 to keep the result as float   

在JavaScript中,浮点与整数间没有区别。事实上,JavaScript中的每个数字都表示使用双精度64位格式IEEE 754。简单理解,所有数字都是浮点。

解决办法:不要使用小数(decimals),转换数字(numbers)到浮点(floats)。

  1. var myNumber = 3.5;   
  2. var myResult = 3.5 + 1; //Result is 4.5, as expected   

8.with()作为快捷方式的用法Usage of with() as a shortcut

举例:

  1. team.attackers.myWarrior = { attack: 1, speed: 3, magic: 5};   
  2. with (team.attackers.myWarrior){   
  3. console.log ( “Your warrior power is ” + (attack * speed));   
  4. }   

讨论with()之前,要明白JavaScript contexts如何工作的。每个函数都有一个执行context(语句),简单来说,包括函数可以访问的所有的变量。因此context包含arguments和定义变量。

with()真正是做什么?是插入对象到context链,它在当前context和父级context间植入。就像你看到的with()的快捷方式会非常慢。

解决办法:不要使用with() for shortcuts,仅for context injection,如果你确实需要时。

  1. team.attackers.myWarrior = { attack: 1, speed: 3, magic: 5};   
  2. var sc = team.attackers.myWarrior;   
  3. console.log(“Your warrior power is ” + (sc.attack * sc.speed)); 

9.setTimeout/setInterval 字符串的用法 Usage of strings with setTimeout/setInterval

举例:

  1. function log1() { console.log(document.location); }   
  2. function log2(arg) { console.log(arg); }   
  3. var myValue = “test”;   
  4. setTimeout(“log1()”, 100);   
  5. setTimeout(“log2(” + myValue + “)”, 200);   

setTimeout()和setInterval()可被或一个函数或一个字符串作为首个参数。如果你传递一个字符串,引擎将创建一个新函数(使用函数构造器),这在一些浏览器中会非常慢。相反,传递函数本身作为首个参数,更快、更强大、更干净。

解决办法:一定不要使用strings for setTimeout()或setInterval()。

  1. function log1() { console.log(document.location); }   
  2. function log2(arg) { console.log(arg); }   
  3. var myValue = “test”;   
  4. setTimeout(log1, 100); //Reference to a function   
  5. setTimeout(function(){ //Get arg value using closures   
  6. log2(arg);   
  7. }, 200);   

10.setInterval()的用法Usage of setInterval() for heavy functions

举例:

  1. function domOperations() {   
  2. //Heavy DOM operations, takes about 300ms   
  3. }   
  4. setInterval(domOperations, 200);   

setInterval()将一函数列入计划被执行,仅是在没有另外一个执行在主执行队列中等待。JavaScript引擎只增加下一个执行到队列如果没有另外一个执行已在队列。这可能导致跳过执行或者运行2个不同的执行,没有在它们之间等待200ms的情况下。

一定要搞清,setInterval()没有考虑进多长时间domOperations()来完成任务。

解决办法:避免 setInterval(),使用 setTimeout()

  1. function domOperations() {   
  2. //Heavy DOM operations, takes about 300ms   
  3. //After all the job is done, set another timeout for 200 ms   
  4. setTimeout(domOperations, 200);   
  5. }   
  6. setTimeout(domOperations, 200);   

11.“this”的滥用Misuse of ‘this’

这个常用错误,没有例子,因为非常难创建来演示。this的值在JavaScript中与其他语言有很大的不同。

函数中的this值被定义是在当函数被调用时,而非声明的时间,这一点非常重要。下面的案例中,函数内this有不同的含义。

* Regular function: myFunction(‘arg1’);

this points to the global object, wich is window for all browers.

* Method: someObject.myFunction(‘arg1’);

this points to object before the dot, someObject in this case.

* Constructor: var something = new myFunction(‘arg1’);

this points to an empty Object.

* Using call()/apply(): myFunction.call(someObject, ‘arg1’);

this points to the object passed as first argument.

12.eval()访问动态属性的用法Usage of eval() to access dynamic properties

举例:

  1. var myObject = { p1: 1, p2: 2, p3: 3};   
  2. var i = 2;   
  3. var myResult = eval(‘myObject.p’+i);   

主要问题在于使用eval()开始一个新的执行语句,会非常的慢。

解决办法:使用方括号表示法(square bracket notation)代替 eval()。

  1. var myObject = { p1: 1, p2: 2, p3: 3};   
  2. var i = 2;   
  3. var myResult = myObject[“p”+i];   

13.未定义(undefined)作为变量的用法Usage of undefined as a variable

举例:

  1. if ( myVar === undefined ) {   
  2. //Do something   
  3. }   

在上面的例子中,未定义实际上是一变量。所有的JavaScript引擎会创建初始化的变量window.undefined给未定义作为值。然而注意的 是变量不仅是可读,任何其他的代码可以刚改它的值。很奇怪能找到window.undefined有来自未定义的不同的值的场景,但是为什么冒险呢?

 

解决办法:检查未定义时,使用typeof。

if ( typeof myVar === “undefined” ) {   //Do something   
}   

转自:http://www.cnblogs.com/JuneZhang/archive/2011/04/19/2020479.html

 

转载于:https://www.cnblogs.com/xufeiyang/articles/3251369.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/360492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php h2,微信连接失败:一直返回h2Moved/h2 (终于搞定了)

这几天都OK的&#xff0c;可以正常访问&#xff0c;统计数据上只出现过一次访问失败&#xff0c;但是平均耗时增加了30%估计是上次那个心脏滴血事件后&#xff0c;腾讯要求停用SSLv3&#xff0c;必须用TLSv1&#xff0c;但是之前一直没有停止SSLv3的支持&#xff0c;现在真停了…

使用Selenium进行Spring Boot集成测试

Web集成测试允许对Spring Boot应用程序进行集成测试&#xff0c;而无需进行任何模拟。 通过使用WebIntegrationTest和SpringApplicationConfiguration我们可以创建加载应用程序并在普通端口上侦听的测试。 Spring Boot的这一小增加使使用Selenium WebDriver创建集成测试变得更加…

begin ~~~

是时候需要用博客记录自己的code life了~~~ 大二暑假~~~ 需要的tech&#xff1a;php linux j2se ssh asp.net c#winform python htmlcssjsajax svngit转载于:https://www.cnblogs.com/tonyluj/p/3252185.html

在Spring MVC流中使用rx-java Observable

Spring MVC现在已经支持异步请求处理流程了一段时间&#xff0c;该支持内部利用了Tomcat / Jetty等容器的Servlet 3异步支持。 Spring Web Async支持 考虑一下需要花一点时间处理的服务呼叫&#xff0c;该服务呼叫具有延迟&#xff1a; public CompletableFuture<Message&…

宝塔php gd库,宝塔面板安装 EasyImag – 一款最简单图床的安装体验

近日闲逛&#xff0c;发现了一款图床&#xff0c;一款开箱即食的简单图床程序。因为没有数据库所以安装起来也是异常简单&#xff0c;我们看看功能&#xff1a;支持设置图片质量支持仅登录后上传支持QQ截图&#xff0c;剪切板上传支持在线管理(增删改查)支持上传图片转换为指定…

php order by where,无合适where条件过滤时尽量选择order by后的字段以驱动表进行查询...

后台查询语句SELECTo.orders_id,s.orders_status_name,ot.text,af.affiliate_idFROMordersoLEFTJOINorders_totalotON(o.orders_idot.orders_id)LEFTJOINaffilia后台查询语句SELECT o.orders_id, s.orders_status_name, ot.text ,af.affiliate_idFROM orders oLEFT JOIN orders…

零垃圾创建数百万个对象

如性能优化第一规则中所述&#xff0c;垃圾是快速代码的敌人。 通过使用垃圾收集器的服务&#xff0c;它不仅会破坏任何形式的确定性性能&#xff0c;而且我们开始在CPU高速缓存中填充垃圾&#xff0c;这将导致程序的高速缓存未命中。 那么&#xff0c;我们可以在不创建垃圾的…

[算法]单链表专题

如何判断链表环的入口位置&#xff1f; 一个指针从头开始单步走&#xff0c;一个指针从第一次相遇位置开始单步走&#xff0c;再相遇的位置就是环入口&#xff0c;证明如下&#xff1a; 设链表头到环入口位置距离为a&#xff0c;入口位置到第一次相遇位置为b&#xff0c;相遇位…

批准Oracle IDM中的特定Web服务

关于Web服务端点的快速发布&#xff0c;OIM和SOA在与批准有关的场景中使用了Web服务端点- 基本内容&#xff0c;但对于初学者可能有用 。 Oracle IDM与SOA套件集成并利用其提供与批准相关的功能&#xff08;说实话&#xff0c;SOA相当丰富&#xff0c;并且也被用作Web服务连接…

Oracle15001,Oracle11gR2RAC环境DBCA创建数据库报错ORA-15055ORA-15001

在Oracle 11gR2 GridInfrastructure和Database软件安装完成之后&#xff0c;执行DBCA创建数据库到30%的时候报如下错误&#xff0c;点击OK后提示忽略并问题现象:在Oracle 11gR2 GridInfrastructure和Database软件安装完成之后&#xff0c;执行DBCA创建数据库到30%的时候报如下错…

linux 下访问mysql

1&#xff1a;先进到root:/# /usr/local/mysql/bin/2&#xff1a;root:/# mysql -u root -p Enter password: 转载于:https://www.cnblogs.com/gaoyinghui/p/3255148.html

针对新手的Java EE7和Maven项目–第8部分

第1部分 &#xff0c; 第2部分 &#xff0c; 第3部分 &#xff0c; 第4部分 &#xff0c; 第5部分 &#xff0c; 第6部分 &#xff0c; 第7部分 第8部分 自上一篇文章以来&#xff0c;这一系列教程已经有很长时间了。 是时候恢复并在我们的简单项目中添加新功能了。 正…

oracle_home path,ORACLE_HOME迁移后需要设置LD_LIBRARY_PATH环境变量

而设置LD_LIBRARY_PATH后&#xff0c;问题解决&#xff1a;[orat3hpserver2 ~]$ export LD_LIBRARY_PATH$ORACLE_HOME/lib[orat3hpserver2 ~]$ sqlplus / AS sysdbaSQL*Plus: Release 10.2.0.4.0 - Production ON Sun Mar 18 16:10:57 2012Copyright (c) 1982, 2007, Oracle. A…

栈的链式存储及其基本运算

#include <stdio.h> #include <stdlib.h> #define M 10typedef struct stnode {char data;struct stnode *next; }LinkStack;void InitStack(LinkStack *&ls) //初始化栈 {lsNULL; }void PushStack(LinkStack *&ls,char x)//进栈 {LinkStack *p;p(LinkSta…

oracle的导出参数statistic,使用expdp导出时评估所需存储容量大小

我们在使用expdp进行数据导出时&#xff0c;可以事先评估需要存储大小容量(bytes)&#xff0c;Oracle可以通过两种方式进行容量估算:[more]1)、通过数据块数量2)、通过统计信息中记录的内容估算具体是通过制定参数estimate_only和estimate来评估导出的性能参数estimate_onlyy|n…

玩Weld-Probe –一站式查看CDI的所有方面

焊接3.0.0.Alpha4被释放 &#xff0c;而我一直坐在在DevConf.CZ一间会议室。 Jozef Hartinger&#xff08; jozefhartinger &#xff09;或多或少地在几分钟前告诉我有关此最新版本的新功能的信息。 有一个特别的功能真正引起了我的注意&#xff0c;它是新的焊接探针机制。 什…

排列、组合问题(递归)

这里主要介绍字符串排列组合问题,高中数学常见的题目,不用详细介绍&#xff0c;看例子就可以解决问题 "1212" 全排列结果为 1212&#xff0c;1221&#xff0c;1122&#xff0c;2112&#xff0c;2121&#xff0c;2211 组合结果是 1,2,12 我所理解的排列组合结果是…

oracle日志文件大小规则,修改oracle日志文件大小

1、创建2个新的日志组alter database add logfile group 4 (D:\ORACLE\ORADATA\ORADB\REDO04_1.LOG) size 1024k;alter database add logfile group 5 (D:\ORACLE\ORADATA\ORADB\REDO05_1.LOG) size 1024k;2、切换当前日志到新的日志组alter system switch logfile;alter syste…

Java开发工具可以促进编程!

Java开发人员通常尝试找到快速有效地编写高质量Java代码的方法&#xff0c;以使他们的编程工作更轻松。 由于情况发生了变化&#xff0c;因此出现了越来越多的工具。 因此&#xff0c;下面列出了大多数开发人员已经使用&#xff0c;将来使用或一定会使用的有用工具。 该列表包括…

linux cmake装在自己目录下,如何在Linux下安装cmake

全部展开OpenCV 2.2和更高版本需要使用Cmake生成生成文件&#xff0c;因此需要先安装cmake. 还有其他需要先安装cmake的软件1. 在Linux环境中打开Web浏览器&#xff0c;输入URL:mac cmake gui&#xff0c;找到最新版本的位置. 通常&#xff0c;发布了两个版本的开源软件: “源分…