编程小贴士

给你的编程提供小点子


45个有用的JavaScript技巧,窍门和最佳实践

在这篇文章中,我将分享一些JavaScript常用的技巧,窍门和最佳实践。不管JavaScript开发者是使用在浏览器/引擎上或者服务器端(SSJS——Service Side JavaScript)JavaScript解释器上,这些他们都是应该知晓的。

需要注意的是,文章中的代码片段均是在最新的Google Chrome(版本号30)上测试过,它使用V8 JavaScript引擎(V8 3.20.17.15)。

  1、第一个给变量分配值时不要忘了var关键字。

分配值给未定义的变量将是该变量自动成为全局变量,应该避免全局变量。

  2、使用===而不是==

==(或!=)操作符在需要时会自动转换变量类型,而===(或!==)则不会执行类型转换。在进行值和类型比较的时候,应首先考虑使用===

[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、undefined、null、0、false、NaN、’’(空字符串)都被视为false。

  4、在行尾使用分号

在行尾使用分号是很好的实践。如果你忘了,也不会得到警告,因为大多数情况下JavaScript解释器会插入分号的。更多关于你为什么要使用分号的细节,可以看看此文:http://davidwalsh.name/javascript-semicolons.

5、创建对象构造函数

function Person(firstName, lastName){
    this.firstName =  firstName;
    this.lastName = lastName;
}
 
var Saad = new Person("Saad", "Mousliki");

 

  6、小心使用typeof、instanceof和constructor

  • typeof:不要忘了typeof null返回object,而大多数对象,typeof(Array, Date, and others)也将返回object
  • constructor:内部原型属性,可以被覆盖(可以参考:又谈原型对象)
  • instanceof:JavaScript的一个用于检查构造函数的原型链的操作符
var arr = ["a", "b", "c"];
typeof arr;   // return "object"
arr  instanceof Array // true
arr.constructor();  //[]

 

7、创建一个自执行函数

这个经常被称为自我调用的匿名函数或者立即调用的函数表达式(IIFE)。当你创建它时,它会自动执行的函数。

(function(){
    // some private code that will be executed automatically
})();
(function(a,b){
    var result = a+b;
    return result;
})(10,20)

 

8、随机获取一个数组项

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

 

9、在特定范围内获取一个随机数

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

 

10、从数字0到最大值之间获取一个数字数组

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

 

  11、生成一个随机字符串

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

 

  12、打乱一个数字数组的元素顺序

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] */

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

 

  14、将一个数组附加到另一个数组
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] */

 

  15、将arguments对象转换成一个数组
var argArray = Array.prototype.slice.call(arguments);

 

  16、验证参数是否是number类型
function isNumber(n){
    return !isNaN(parseFloat(n)) && isFinite(n);
}

 

  17、验证参数是否是数组
function isArray(obj){
    return Object.prototype.toString.call(obj) === '[object Array]' ;
}

 

  注意,toString()方法被重写,使用这个技巧将得不到期望的结果了。或者可以这样:
Array.isArray(obj); // 这是一个新的array的方法

 

如果你不在使用多重frames的情况下,你还可以使用 instanceof 方法。但如果你有多个上下文,你就会得到错误的结果。
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; // false

 

  18、获取数字数组中的最大值和最小值
var  numbers = [5, 458 , 120 , -215 , 228 , 400 , 122205, -85411];
var maxInNumbers = Math.max.apply(Math, numbers);
var minInNumbers = Math.min.apply(Math, numbers);

 

  19、清空一个数组
var myArray = [12 , 222 , 1000 ];
myArray.length = 0; // myArray will be equal to [].

 

  20、不要使用delete去删除一个数组项
  使用 split 而不要使用 delte 来删除数组中的某个项。使用 delete 只是用 undefined 来替换掉原有的项,并不是真正的从数组中删除。不要用如下的方式
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]   */

而是用下列的方式

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来删除一个对象的属性

  21、使用 length 来截短一个数组
  跟上面的清空数组的方式类似,我们使用 length 属性来截短一个数组。
var myArray = [12 , 222 , 1000 , 124 , 98 , 10 ];
myArray.length = 4; // myArray will be equal to [12 , 222 , 1000 , 124].

 

此外,如果你将一个数组的 length 设置成一个比现在大的值,那么这个数组的长度就会被改变,会增加新的 undefined 的项补上。 数组的 length 属性是可读写的。

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

 

  22、在条件中使用逻辑运算符:AND、OR

var foo = 10;
foo == 10 && doSomething(); // 等价于 if (foo == 10) doSomething();
foo == 5 || doSomething(); // 等价于 if (foo != 5) doSomething();

 

OR可以用于给函数设置默认参数

function doSomething(arg1){
    Arg1 = arg1 || 10; // 如果arg1没有被设置的话,Arg1将被默认设成10
}

 

  23、使用 map() 方法来遍历一个数组里的项

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

 

  24、保留小数位

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

 

  25、浮点数问题

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

 

为什么是false?0.1+0.2等于0.30000000000000004。别忘了,所有的JavaScript数字在内部都是以64位二进制表示的浮点数,符合IEEE 754标准。更多的介绍,可以阅读this blog post.你可以使用 toFixed() 和 toPrecision() 方法解决这个问题。

  26、使用for-in遍历一个对象内部属性的时候注意检查

下面的代码片段能够避免在遍历一个对象属性的时候访问原型的属性

for (var name in object) {
    if (object.hasOwnProperty(name)) {
        // do something with name
    }
}

 

  27、逗号运算符

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

 

  28、缓存需要查询或计算的变量

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

 

  29、将参数传给isFinite()之前要验证

isFinite(0/0) ; // false
isFinite("foo"); // false
isFinite("10"); // true
isFinite(10);   // true
isFinite(undifined);  // false
isFinite();   // false
isFinite(null);  // true  !!!

 

  30、避免数组中的负索引

var numbersArray = [1,2,3,4,5];
var from = numbersArray.indexOf("foo") ;  // from is equal to -1
numbersArray.splice(from,2);    // will return [5]
  确保传递给splice()的参数不是负数。
   31、对JSON进行序列化和反序列化
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  */

 

  32、避免使用eval()和Function()构造函数

使用 eval 和 Function 构造函数是非常昂贵的操作,因为每次他们都会调用脚本引擎将源代码转换成可执行代码。

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

 

  33、避免使用with

使用 with() 会插入一个全局变量。因此,同名的变量会被覆盖值而引起混淆。

  34、避免用for-in循环一个数组

不要这么使用

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

 

有更好的方式

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

 

  35、传函数给setTimeout()和setInterval()而不是字符串

如果你将字符串传递给 setTimeout() 或者 setInterval(),这个字符串将被如使用 eval 一样被解析,这个是非常耗时的。不要使用:

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

 

建议使用

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

 

  36、使用 switch/case 语句,而不是一系列的 if/else

在2中情况以上的时候,使用 switch/case 更高效,而且更优雅(更易于组织代码)。但在判断的情况超过10种的时候不要使用 switch/case。

  37、判断数值范围时使用 switch/case

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"

 

  38、为创建的对象指定prototype

写一个函数来创建一个以指定参数作为prototype的对象是有可能:

function clone(object) {
    function OneShotConstructor(){};
    OneShotConstructor.prototype= object;
    return new OneShotConstructor();
}
clone(Array).prototype ;  // []

 

  39、HTML转义函数

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

 

  40、避免在循环内部使用try-catch-finally

在运行时,每次当 catch 从句被执行的时候,被捕获的异常对象会赋值给一个变量,而在 try-catch-finally 结构中,每次都会新建这个变量。不要这样用:

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
    }
}

 

而是这样子用

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
}

 

  41、给XMLHttpRequests设置超时

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();

 

  42、处理WebSocket超时

通常当WebSocket连接建立的时候,如果30秒内没有活动,服务器将暂停连接,同样的道理,防火墙也会暂停连接。

为了防止超时的问题,你可能需要间隔地向服务器端发送空消息。要这样做的话,你可以在你的代码里添加下面的两个函数:一个用来保持连接,另一个用来取消连接的保持。通过这个技巧,你可以控制超时的问题。

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() 方法的最后。

  43、记住:原始运算符始终比函数调用要搞笑。使用 VanillaJS

  例如,不要使用这个

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

 

而是用这个代替

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

 

  44、当编码的时候,要保持代码整洁。上线之前对代码进行压缩。

  45、JavaScript是极好的:Best Resources To Learn JavaScript

    • Code Academy JavaScript tracks: http://www.codecademy.com/tracks/javascript
    • Eloquent JavaScript by Marjin Haverbeke: http://eloquentjavascript.net/
    • Advanced JavaScript by John Resig: http://ejohn.org/apps/learn/

75 Responses to “ 45个有用的JavaScript技巧,窍门和最佳实践 ”

  1. mia pron khalifa说道:

    Z7505k Thanks for sharing, this is a fantastic blog.Thanks Again. Keep writing.

  2. please stop by the sites we follow, such as this a single, because it represents our picks in the web

  3. coloring page说道:

    Really appreciate you sharing this blog article.Thanks Again. Fantastic.

  4. Looking forward to reading more. Great post.Much thanks again.

  5. My Face Gifts说道:

    I will right away grab your rss feed as I can not find your email subscription link or newsletter service. Do you ave any? Kindly let me know in order that I could subscribe. Thanks.

  6. click here说道:

    You ave made some good points there. I checked on the net to learn more about the issue and found most individuals will go along with your views on this web site.

  7. My Face Gifts说道:

    You made some really good points there. I checked on the net for more information about the issue and found most people will go along with your views on this web site.

  8. learn more说道:

    Major thankies for the blog article. Much obliged.

  9. Very good post. I absolutely appreciate this site. Keep it up!

  10. home说道:

    I was suggested this blog by my cousin. I am not sure whether this post is written by him as no one else know such detailed about my difficulty. You are incredible! Thanks!

  11. Some really prime posts on this web site , saved to bookmarks.

  12. Mca benefits说道:

    MANIC STREET PREACHERS I Think Ive Found It Shalala.ru

  13. pre booked说道:

    Really superb information can be found on site.

  14. Just Browsing While I was surfing yesterday I saw a great article about

  15. status online说道:

    Wow, great article post.Really thank you! Keep writing.

  16. Very good information. Lucky me I came across your blog by accident (stumbleupon). I ave book-marked it for later!

  17. And说道:

    I truly appreciate this post. I ave been looking all over for this! Thank goodness I found it on Bing. You have made my day! Thanks again!

  18. Keep up the fantastic piece of work, I read few blog posts on this web site and I believe that your site is real interesting and has lots of great information.

  19. klm coupon code说道:

    In truth, your creative writing abilities has inspired me to get my very own site now

  20. I thought it was going to be some boring old publish, but it really compensated for my time. I will publish a link to this page on my weblog. I am sure my visitors will find that really useful

  21. Thanks for the post.Really thank you! Great.

  22. Thank you for your article post.Much thanks again. Awesome.

  23. Muchos Gracias for your article post.Really looking forward to read more. Awesome.

  24. Some genuinely quality posts on this internet site, saved to fav.

  25. Major thanks for the article.Thanks Again. Much obliged.

  26. This is one awesome blog post. Fantastic.

  27. Online说道:

    of the subjects you write related to here. Again, awesome web site!

  28. Perfect just what I was looking for!.

  29. adidas nmd说道:

    I have to show appreciation to the writer just for bailing me out of this incident. Just after surfing around through the world wide web and getting techniques which are not pleasant, I figured my entire life was well over. Being alive devoid of the answers to the difficulties you have sorted out through the short post is a crucial case, as well as those which might have in a wrong way affected my career if I hadn’t come across your blog. Your good competence and kindness in playing with all the pieces was useful. I’m not sure what I would have done if I hadn’t come across such a subject like this. I am able to at this point look ahead to my future. Thanks a lot so much for this skilled and results-oriented guide. I won’t think twice to suggest the blog to any individual who ought to have tips on this problem.

  30. Blogging说道:

    Informative and precise Its difficult to find informative and precise information but here I found

  31. stella说道:

    Jet Set in Style with Esembles Collection

  32. Upload your photos, host your videos, and share them with friends and family.

  33. Ganchillo说道:

    Thanks again for the blog.Much thanks again. Want more.

  34. online说道:

    This is a great tip especially to those fresh to the blogosphere. Short but very precise information Appreciate your sharing this one. A must read post!

  35. value说道:

    Its like you read my mind! You seem to know so much about this, like you wrote

  36. Roman Polanski How do I allow contributors to see only their uploads in WordPress?

  37. That as what i call аАТ’аЂа‹great postаАТ’аЂа›. Thank you so much.

  38. hampton bay说道:

    Incredible! This blog looks exactly like my old one! It as on a totally different topic but it has pretty much the same layout and design. Great choice of colors!

  39. Im thankful for the blog.Really thank you! Really Great.

  40. Waec expo说道:

    Wow, awesome blog layout! How long have you been blogging for? you make blogging look easy. The overall look of your web site is great, as well as the content!. Thanks For Your article about sex.

  41. Waec expo说道:

    Some really great information, Glad I noticed this.

  42. ps4 ark servers说道:

    I wanted to thank you for this very good read!! I definitely enjoyed every bit of it. I ave got you saved as a favorite to check out new things you post

  43. Thanks for sharing, this is a fantastic post.Really looking forward to read more. Want more.

  44. oral sex说道:

    This is very interesting, You are a very skilled blogger. I have joined your feed and look forward to seeking more of your wonderful post. Also, I have shared your web site in my social networks!

  45. I visited a lot of website but I believe this one contains something special in it in it

  46. tm objection说道:

    Really enjoyed this blog post.Really thank you! Great.

  47. Really enjoyed this article post.Much thanks again. Awesome.

  48. Just thought i would comment and say neat design, did you code it yourself? Looks great. Just found here

  49. tips说道:

    outside to get their fairly fairly sweet as well as her cast and crew, including producer Judd

  50. hotel说道:

    It’а†s actually a nice and useful piece of information. I’а†m satisfied that you shared this useful information with us. Please keep us up to date like this. Thank you for sharing.

  51. This is a great tip particularly to those new to the blogosphere. Short but very precise info Many thanks for sharing this one. A must read article!

  52. Open Heavens说道:

    Thanks for the article.Much thanks again. Awesome.

  53. over it all at the minute but I have bookmarked it and also added your RSS

  54. more information说道:

    Major thankies for the article post.Really looking forward to read more. Much obliged.

  55. Simply wanna input that you have a very nice web site , I love the style and design it actually stands out.

  56. There is visibly a bundle to realize about this. I assume you made various nice points in features also.

  57. view说道:

    Im thankful for the blog post.Really thank you! Will read on

  58. have a look at说道:

    We all talk just a little about what you should speak about when is shows correspondence to because Perhaps this has much more than one meaning.

  59. to learn more说道:

    Really superb information can be found on blog.

  60. Nnamdi说道:

    There is definately a lot to find out about this topic. I really like all the points you made.

  61. miller electric说道:

    respective fascinating content. Make sure you update this

  62. announce online说道:

    if you are if you are in an apartment that is confined, then folding tables would be very well suited for you;;

  63. Only a smiling visitant here to share the love (:, btw outstanding style and design. Reading well is one of the great pleasures that solitude can afford you. by Harold Bloom.

  64. Normally I don at read post on blogs, but I wish to say that this write-up very forced me to try and do it! Your writing style has been amazed me. Thanks, very great post.

  65. take a look at说道:

    Touche. Outstanding arguments. Keep up the great work.

  66. Really appreciate you sharing this post.Thanks Again. Cool.

  67. Really enjoyed this article.Really looking forward to read more. Fantastic.

  68. official site说道:

    I think this is a real great post.Really thank you! Really Great.

  69. Luxury Watches说道:

    There as certainly a lot to learn about this topic. I love all the points you have made.

  70. tampa seo说道:

    What as Happening i am new to this, I stumbled upon this I ave found It absolutely helpful and it has aided me out loads. I hope to contribute & aid other users like its helped me. Good job.

  71. I simply could not leave your web site prior to suggesting that I really enjoyed the usual information a person supply in your guests? Is gonna be again steadily to investigate cross-check new posts

  72. good morning说道:

    the Zune Social is also great fun, letting you find others with shared tastes and becoming friends with them.

  73. Well I sincerely liked studying it. This tip procured by you is very useful for accurate planning.

  74. produce a good article but what can I say I procrastinate a whole

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>