众所周知,JavaScript是一门非常流行的编程语言,开发者用它不仅可以开发出炫丽的Web程序,还可以用它来开发一些移动应用程序(如PhoneGap或Appcelerator),它还有一些服务端实现,比如NodeJS、Wakanda以及其它实现。此外,许多开发者都会把JavaScript选为入门语言,使用它来做一些弹出窗口等小东西。

  在这篇文章中,作者将会向大家分享JavaScript开发的小技巧、最佳实践等非常实用的内容,不管你是前端开发者还是服务端开发者,都应该来看看这些小技巧,它们绝对会让你受益的。

  文中所提供的代码片段都已经过最新版的Chrome 30测试,该浏览器使用V8 JavaScript引擎(V8 3.20.17.15)。

  1.第一次给变量赋值时,别忘记var关键字

  给一个未声明的变量赋值,该变量会被自动创建为全局变量,在JS开发中,应该避免使用全局变量。

  2.使用===替换==

  并且永远不要使用=或!=。

1
2
3
4
5
6
7
8
[10] === 10    // is false
[10]  == 10    // is true
'10' == 10     // is true
'10' === 10    // is false
 []   == 0     // is true
 [] ===  0     // is false
 '' == false   // is true but true == "a" is false
 '' ===   false // is false

  3.使用分号来作为行终止字符

  在行终止的地方使用分号是一个很好的习惯,即使开发人员忘记加分号,编译器也不会有任何提示,因为在大多数情况下,JavaScript解析器会自动加上。

  4.创建构造函数

1
2
3
4
5
6
function Person(firstName, lastName){
    this.firstName =  firstName;
    this.lastName = lastName;       
} 
 
var Saad = new Person("Saad", "Mousliki");

  5.应当小心使用typeof、instanceof和constructor

1
2
3
4
var arr = ["a", "b", "c"];
typeof arr;   // return "object"
arr  instanceof Array // true
arr.constructor();  //[]

  6.创建一个Self-calling函数

  这通常会被称为自我调用的匿名函数或立即调用函数表达式(LLFE)。当函数被创建的时候就会自动执行,好比下面这个:

1
2
3
4
5
6
7
(function(){
    // some private code that will be executed automatically
})(); 
(function(a,b){
    var result = a+b;
    return result;
})(10,20)

  7.给数组创建一个随机项

1
2
3
var items = [12, 548 , 'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' , 2145 , 119];
 
var  randomItem = items[Math.floor(Math.random() * items.length)];

  8.在特定范围里获得一个随机数

  下面这段代码非常通用,当你需要生成一个假的数据用来测试时,比如在最低工资和最高之前获取一个随机值。

1
var x = Math.floor(Math.random() * (max - min + 1)) + min;

  9.在数字0和最大数之间生成一组随机数

1
2
3
var numbersArray = [] , max = 100;
 
for( var i=1; numbersArray.push(i++) < max;);  // numbers = [0,1,2,3 ... 100]

  10.生成一组随机的字母数字字符

1
2
3
4
5
6
function generateRandomAlphaNum(len) {
    var rdmstring = "";
    for( ; rdmString.length < len; rdmString  += Math.random().toString(36).substr(2));
    return  rdmString.substr(0, len);
 
}

  11.打乱数字数组

1
2
3
var numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
numbers = numbers.sort(function(){ return Math.random() - 0.5});
/* the array numbers will be equal for example to [120, 5, 228, -215, 400, 458, -85411, 122205]  */

  12.字符串tim函数

  trim函数可以删除字符串的空白字符,可以用在Java、C#、PHP等多门语言里。

1
String.prototype.trim = function(){return this.replace(/^\s+|\s+$/g, "");};

  13.数组追加

1
2
3
4
5
var array1 = [12 , "foo" , {name "Joe"} , -2458];
 
var array2 = ["Doe" , 555 , 100];
Array.prototype.push.apply(array1, array2);
/* array1 will be equal to  [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */

  14.将参数对象转换为数组

1
var argArray = Array.prototype.slice.call(arguments);

  15.验证一个给定参数是否为数字

1
2
3
function isNumber(n){
    return !isNaN(parseFloat(n)) && isFinite(n);
}

  16.验证一个给定的参数为数组

1
2
3
function isArray(obj){
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}

  注意,如果toString()方法被重写了,你将不会得到预期结果。

  或者你可以这样写

1
Array.isArray(obj); // its a new Array method

  同样,如果你使用多个frames,你可以使用instancesof,如果内容太多,结果同样会出错。

1
2
3
4
5
6
7
8
9
var myFrame = document.createElement('iframe');
document.body.appendChild(myFrame);
 
var myArray = window.frames[window.frames.length-1].Array;
var arr = new myArray(a,b,10); // [a,b,10] 
 
// instanceof will not work correctly, myArray loses his constructor
// constructor is not shared between frames
arr instanceof Array; // fals

  17.从数字数组中获得最大值和最小值

1
2
3
var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
var maxInNumbers = Math.max.apply(Math, numbers);
var minInNumbers = Math.min.apply(Math, numbers);

  18.清空数组

1
2
var myArray = [12 , 222 , 1000 ]; 
myArray.length = 0; // myArray will be equal to [].

  19.不要用delete从数组中删除项目

  开发者可以使用split来代替使用delete来删除数组项。与其删除数组中未定义项目,还不如使用delete来替代。

1
2
3
4
5
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
delete items[3]; // return true
items.length; // return 11
/* items will be equal to [12, 548, "a", undefined × 1, 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */

  也可以……

1
2
3
4
5
var items = [12, 548 ,'a' , 2 , 5478 , 'foo' , 8852, , 'Doe' ,2154 , 119 ];
items.length; // return 11
items.splice(3,1) ;
items.length; // return 10
/* items will be equal to [12, 548, "a", 5478, "foo", 8852, undefined × 1, "Doe", 2154,       119]   */

  delete方法应该删除一个对象属性

  20.使用length属性缩短数组

  如上文提到的清空数组,开发者还可以使用length属性缩短数组。

1
2
var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ]; 
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

  如果你所定义的数组长度值过高,那么数组的长度将会改变,并且会填充一些未定义的值到数组里,数组的length属性不是只读的。

1
2
myArray.length = 10; // the new array length is 10
myArray[myArray.length - 1] ; // undefined

  文中所提供的代码片段都已经过最新版的Chrome 30测试,该浏览器使用V8 JavaScript引擎(V8 3.20.17.15)。

  1.使用逻辑符号&&或者||进行条件判断

1
2
3
var foo = 10; 
foo == 10 && doSomething(); // is the same thing as if (foo == 10) doSomething();
foo == 5 || doSomething(); // is the same thing as if (foo != 5) doSomething();

  AND也可以用来设置函数参数的默认值

1
2
3
Function doSomething(arg1){
    Arg1 = arg1 || 10; // arg1 will have 10 as a default value if it’s not already set
}

  2.使用map()方法来遍历数组

1
2
3
4
var squares = [1,2,3,4].map(function (val) { 
    return val * val; 
});
// squares will be equal to [1, 4, 9, 16]

  3.舍入小数位数

1
2
var num =2.443242342;
num = num.toFixed(4);  // num will be equal to 2.4432

  4.浮点数问题

1
2
3
0.1 + 0.2 === 0.3 // is false
9007199254740992 + 1 // is equal to 9007199254740992 
9007199254740992 + 2 // is equal to 9007199254740994

  0.1+0.2等于0.30000000000000004,为什么会发生这种情况?根据IEEE754标准,你需要知道的是所有JavaScript数字在64位二进制内的都表示浮点数。开发者可以使用toFixed()和toPrecision()方法来解决这个问题。

  5.使用for-in loop检查遍历对象属性

  下面这段代码主要是为了避免遍历对象属性。

1
2
3
4
5
for (var name in object) { 
    if (object.hasOwnProperty(name)) {
        // do something with name                   
    } 
}

  6.逗号操作符

1
2
3
4
var a = 0;
var b = ( a++, 99 );
console.log(a);  // a will be equal to 1
console.log(b);  // b is equal to 99

  7.计算或查询缓存变量

  在使用jQuery选择器的情况下,开发者可以缓存DOM元素

1
2
3
4
var navright = document.querySelector('#right');
var navleft = document.querySelector('#left');
var navup = document.querySelector('#up');
var navdown = document.querySelector('#down');

  8.在将参数传递到isFinite()之前进行验证

1
2
3
4
5
6
7
isFinite(0/0) ; // false
isFinite("foo"); // false
isFinite("10"); // true
isFinite(10);   // true
isFinite(undifined);  // false
isFinite();   // false
isFinite(null);  // true  !!!

  9.在数组中避免负向索引

1
2
3
var numbersArray = [1,2,3,4,5];
var from = numbersArray.indexOf("foo") ;  // from is equal to -1
numbersArray.splice(from,2);    // will return [5]

  确保参数传递到indexOf()方法里是非负向的。

  10.(使用JSON)序列化和反序列化

1
2
3
4
5
var person = {name :'Saad', age : 26, department : {ID : 15, name : "R&D"} };
var stringFromPerson = JSON.stringify(person);
/* stringFromPerson is equal to "{"name":"Saad","age":26,"department":{"ID":15,"name":"R&D"}}"   */
var personFromString = JSON.parse(stringFromPerson); 
/* personFromString is equal to person object  */

  11.避免使用eval()或Function构造函数

  eval()和Function构造函数被称为脚本引擎,每次执行它们的时候都必须把源码转换成可执行的代码,这是非常昂过的操作。

1
2
var func1 = new Function(functionCode);
var func2 = eval(functionCode);

  12.避免使用with()方法

  如果在全局区域里使用with()插入变量,那么,万一有一个变量名字和它名字一样,就很容易混淆和重写。

  13.避免在数组里使用for-in loop

  而不是这样用:

1
2
3
4
var sum = 0; 
for (var i in arrayNumbers) { 
    sum += arrayNumbers[i]; 
}

  这样会更好:

1
2
3
4
var sum = 0; 
for (var i = 0, len = arrayNumbers.length; i < len; i++) { 
    sum += arrayNumbers[i]; 
}

  这样会更快:

1
for (var i = 0; i < arrayNumbers.length; i++)

  为什么?数组长度arraynNumbers在每次loop迭代时都会被重新计算。

  14.不要向setTimeout()和setInterval()方法里传递字符串

  如果在这两个方法里传递字符串,那么字符串会像eval那样重新计算,这样速度就会变慢,而不是这样使用:

1
2
setInterval('doSomethingPeriodically()', 1000); 
setTimeOut('doSomethingAfterFiveSeconds()', 5000);

  相反,应该这样用:

1
2
setInterval(doSomethingPeriodically, 1000); 
setTimeOut(doSomethingAfterFiveSeconds, 5000);

  15.使用switch/case语句代替较长的if/else语句

  如果有超过2个以上的case,那么使用switch/case速度会快很多,而且代码看起来更加优雅。

  16.遇到数值范围时,可以选用switch/casne

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function getCategory(age) { 
    var category = ""; 
    switch (true) { 
        case isNaN(age): 
            category = "not an age"; 
            break; 
        case (age >= 50): 
            category = "Old"; 
            break; 
        case (age <= 20): 
            category = "Baby"; 
            break; 
        default: 
            category = "Young"; 
            break; 
    }; 
    return category; 
} 
getCategory(5);  // will return "Baby"

  17.创建一个对象,该对象的属性是一个给定的对象

  可以编写一个这样的函数,创建一个对象,该对象属性是一个给定的对象,好比这样:

1
2
3
4
5
6
function clone(object) { 
    function OneShotConstructor(){};
    OneShotConstructor.prototype= object; 
    return new OneShotConstructor();
}
clone(Array).prototype ;  // []

  18.一个HTML escaper函数

1
2
3
4
5
6
function escapeHTML(text) { 
    var replacements= {"<": "<", ">": ">","&": "&", "\"": """};                     
    return text.replace(/[<>&"]/g, function(character) { 
        return replacements[character]; 
    });
}

  19.在一个loop里避免使用try-catch-finally

  try-catch-finally在当前范围里运行时会创建一个新的变量,在执行catch时,捕获异常对象会赋值给变量。

  不要这样使用:

1
2
3
4
5
6
7
8
9
var object = ['foo', 'bar'], i; 
for (i = 0, len = object.length; i <len; i++) { 
    try { 
        // do something that throws an exception
    } 
    catch (e) {  
        // handle exception 
    }
}

  应该这样使用:

1
2
3
4
5
6
7
8
9
var object = ['foo', 'bar'], i; 
try {
    for (i = 0, len = object.length; i <len; i++) { 
        // do something that throws an exception
    }
}
catch (e) {  
    // handle exception 
}

  20.给XMLHttpRequests设置timeouts 

  如果一个XHR需要花费太长时间,你可以终止链接(例如网络问题),通过给XHR使用setTimeout()解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
var xhr = new XMLHttpRequest ();
xhr.onreadystatechange = function () { 
    if (this.readyState == 4) { 
        clearTimeout(timeout); 
        // do something with response data
    } 
} 
var timeout = setTimeout( function () { 
    xhr.abort(); // call error callback 
}, 60*1000 /* timeout after a minute */ );
xhr.open('GET', url, true); 
 
xhr.send();

  此外,通常你应该完全避免同步Ajax调用。

  21.处理WebSocket超时

  一般来说,当创建一个WebSocket链接时,服务器可能在闲置30秒后链接超时,在闲置一段时间后,防火墙也可能会链接超时。

  为了解决这种超时问题,你可以定期地向服务器发送空信息,在代码里添加两个函数:一个函数用来保持链接一直是活的,另一个用来取消链接是活的,使用这种方法,你将控制超时问题。

  添加一个timeID……

1
2
3
4
5
6
7
8
9
10
11
12
13
var timerID = 0;
function keepAlive() {
    var timeout = 15000; 
    if (webSocket.readyState == webSocket.OPEN) { 
        webSocket.send(''); 
    } 
    timerId = setTimeout(keepAlive, timeout); 
} 
function cancelKeepAlive() { 
    if (timerId) { 
        cancelTimeout(timerId); 
    } 
}

  keepAlive()方法应该添加在WebSocket链接方法onOpen()的末端,cancelKeepAlive()方法放在onClose()方法下面。

  22.记住,最原始的操作要比函数调用快

  对于简单的任务,最好使用基本操作方式来实现,而不是使用函数调用实现。

  例如

1
2
var min = Math.min(a,b);
A.push(v);

  基本操作方式:

1
2
var min = a < b ? a b;
A[A.length] = v;

  23.编码时注意代码的美观、可读

  JavaScript是一门非常好的语言,尤其对于前端工程师来说,JavaScript也非常重要,点击 这里可以访问更多优秀的JavaScript资源。

【转】超实用的JavaScript技巧及最佳实践的更多相关文章

  1. 超实用的JavaScript技巧及最佳实践

    众所周知,JavaScript是一门非常流行的编程语言,开发者用它不仅可以开发出炫丽的Web程序,还可以用它来开发一些移动应用程序(如PhoneGap或Appcelerator),它还有一些服务端实现 ...

  2. 超实用的JavaScript技巧及最佳实践(上)

    在这篇文章中,作者将会向大家分享JavaScript开发的小技巧.最佳实践等非常实用的内容,不管你是前端开发者还是服务端开发者,都应该来看看这些小技巧,它们绝对会让你受益的. 文中所提供的代码片段都已 ...

  3. 超实用的JavaScript技巧及最佳实践(下)

    1.使用逻辑符号&&或者||进行条件判断 1 2 3 var foo = 10;  foo == 10 && doSomething(); // is the same ...

  4. 20个超实用的JavaScript技巧及最佳实践

    1.第一次给变量赋值时,别忘记var关键字   给一个未声明的变量赋值,该变量会被自动创建为全局变量,在JS开发中,应该避免使用全局变量.   2.使用===替换==   并且永远不要使用=或!=. ...

  5. 超实用的JavaScript技巧及最佳实践给

    1.数组创建一个随机项 var items = [12,548,'a',2,5478,'foo',8852,,'Doe',2145,119]; var randomItem = items[Math. ...

  6. javascript编程的最佳实践推荐

    推荐的javascript编程的最佳实践,摘要记录在这里: 可维护的代码保证代码的性能部署代码 1 可维护的代码1.1什么是维护的代码:可理解性——其他人可以接手代码并理解它的意图和一般途径,而无需原 ...

  7. 避免Java应用中NullPointerException的技巧和最佳实践

    Java应用中抛出的空指针异常是解决空指针的最好方式,也是写出能顺利工作的健壮程序的关键.俗话说"预防胜于治疗",对于这么令人讨厌的空指针异常,这句话也是成立的.值得庆幸的是运用一 ...

  8. (译) 《Javascript 24条最佳实践》

    (摘录) <Javascript 24条最佳实践> 自己一直偏向于实用主义,不是学院派,不是学究派,只讲究把东西能够很好的做出来,但经过一段时间的开发工作当自己总结出来一些东西时,觉得挺有 ...

  9. nodejs进阶(1)——npm使用技巧和最佳实践

    nodejs进阶教程,小白绕道!!! npm使用技巧和最佳实践 前提:请确保安装了node.js npm的最佳实践 npm install是最常见的npm cli命令,但是它还有更多能力!接下来你会了 ...

随机推荐

  1. ASP.NET MVC系列:添加模型

    模型(Model)是应用程序中用于处理应用程序数据逻辑的部分;通常模型对象在数据库中存取数据 添加模型类 在解决方案中右击Models文件夹,然后选择“添加”,在“添加”项里选择“类”:或者选中Mod ...

  2. css异常

    1.0 样式的引用顺序不对会导致样式显示不正常.个人推荐:把别人写好的样式引用在最前面,自己写的放在后面. 2.0 UC手机浏览器 UC手机浏览器在识别到页面文字很多的情况下会自动放大字体优化阅读体验 ...

  3. JavaBean 的小知识点

    /** * @author http://roucheng.cnblogs.com * @version 2016-05-08 */ public class Person { private Str ...

  4. java.lang.IllegalStateException: Recursive entry to executePendingTransactions

    [解决办法]: 将getFragmentManager改为getChildFragmentManager即可

  5. hive安装--设置mysql为远端metastore

    作业任务:安装Hive,有条件的同学可考虑用mysql作为元数据库安装(有一定难度,可以获得老师极度赞赏),安装完成后做简单SQL操作测试.将安装过程和最后测试成功的界面抓图提交 . 已有的当前虚拟机 ...

  6. Permit.js – 用于构建多状态原型的 jQuery 插件

    Permit.js 是一个 jQuery 插件,用于构建交互的,多态的网站原型和应用程序原型.也许你的网站有的功能仅适用于登录的成员,只有管理员才能使用或者你的应用程序会根据线上或离线有不同的功能,这 ...

  7. Node.js Web 开发框架大全《中间件篇》

    这篇文章与大家分享优秀的 Node.js 中间件模块.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编写能够处 ...

  8. Web 开发人员必备的12款 Chrome 扩展程序

    之前已经分享过一些帮助 Web 开发人员和设计师的 Chrome 扩展,这次我们继续展示一组很有用的 Chrome 应用程序.这些免费的 Chrome 应用程序可以简化您的工作流程,为了加快您的工作流 ...

  9. HTML5 模拟现实物理效果,感受 Web 技术魅力

    Ball Pool 是一个基于 HTML5 技术的实验,模拟现实物理效果,让你在 Web 中感受自然物体的运动.玩法介绍:可以随意拖动圆球.点击页面背景.晃动浏览器.双击页面背景或者按住鼠标左键,有不 ...

  10. reactjs学习一(环境搭配react+es6+webpack热部署)

    reactjs学习一(环境搭配react+es6+webpack热部署) 本文的源码在这里下载 https://github.com/tianxiangbing/webpack-study   或者使 ...