十个神奇的JavaScript技巧

善用这些技巧能让你事半功倍
服务器君一共花费了225.849 ms进行了5次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

It doesn’t matter how many years I’ve been dealing with Javascript – it contains many little things that surprises me almost every week. For me, Javascript means a constant learning process.

In this article, I’ll provide ten small Javascript tips, mainly aimed for beginner and intermediate Javascript developers. Hopefully there’s at least one useful tip for every reader :).

尽管我使用Javascript来做开发有很多年了,但它常有一些让我很惊讶的小特性。对于我来说,Javascript是需要持续不断的学习的。在这篇文章中,我将列出10个Javascript使用小技巧,主要面向Javascript新手和中级开发者。希望每个读者都能至少从中学到一个有用的技巧。

1. Variables conversions 变量转换

This sounds quite obvious, but as far I’ve seen, using object constructors, like Array() or Number() for converting variables is quite common practice.

Always use primitive data types (sometimes referred as literals) for converting variables. These won’t do any extra tricks and they usually have better performance.

看起来很简单,但据我所看到的,使用构造函数,像Array()或者Number()来进行变量转换是常用的做法。始终使用原始数据类型(有时也称为字面量)来转换变量,这种没有任何额外的影响的做法反而效率更高。

var myVar   = "3.14159",  
    str     = ""+ myVar,//  to string  
    int     = ~~myVar,  //  to integer  
    float   = 1*myVar,  //  to float  
    bool    = !!myVar,  /*  to boolean - any string with length 
                            and any number except 0 are true */  
    array   = [myVar];  //  to array  

Converting to dates (new Date(myVar)) and regular expressions (new RegExp(myVar)) must be done with constructors. However, always use /pattern/flags when creating regular expressions.

转换日期(new Date(myVar))和正则表达式(new RegExp(myVar))必须使用构造函数,而且创建正则表达式的时候要使用/pattern/flags的形式。

2. Converting decimals to hex or octals and vice versa 十进制转换为十六进制或者八进制,或者反过来

Are you writing separate functions for hex (or octal) conversios? Stop. This can be easily done with existing methods:

你是不是写个单独的函数来转换十六进制(或者八进制)呢?马上停下吧!有更容易的现成的函数可以用:

(int).toString(16); // converts int to hex, eg 12 => "C"  
(int).toString(8);  // converts int to octal, eg. 12 => "14"  
parseInt(string, 16) // converts hex to int, eg. "FF" => 255  
parseInt(string, 8) // converts octal to int, eg. "20" => 16  

3. More playing with numbers 玩转数字

In addition to previous section, here are some more small tricks with when dealing with numbers.

除了上一节介绍的之外,这里有更多的处理数字的技巧。

0xFF; // Hex declaration, returns 255  
020; // Octal declaration, returns 16  
1e3; // Exponential, same as 1 * Math.pow(10,3), returns 1000  
(1000).toExponential(); // Opposite with previous, returns 1e3  
(3.1415).toFixed(3); // Rounding the number, returns "3.142"  

4. Javascript Version Detection Javascript版本检测

Are you aware which version of Javascript your browser supports? If not, check Javascript Versions sheet from Wikipedia.

For some reason, features in Javascript version 1.7 are not widely supported. However, most browsers released within a year support features in version 1.8 (and in 1.8.1).

Note: all the versions of Internet Explorer (8 and older) supports only Javascript version 1.5.

Here’s a tiny script both for detecting the version of Javascript via feature detection. It also allows checking support for specific version of Javascript:

你知道你的浏览器支持哪一个版本的Javascript吗?如果不知道的话,去维基百科查一下Javascript版本表吧。出于某种原因,Javascript 1.7版本的某些特性是没有得到广泛的支持。不过大部分浏览器都支持了1.8版和1.8.1版的特性。(注:所有的IE浏览器(IE8或者更老的版本)只支持1.5版的Javascript)这里有一个脚本,既能通过检测特征来检测JavaScript版本,它还能检查特定的Javascript版本所支持的特性。

var JS_ver  = [];  
  
(Number.prototype.toFixed)?JS_ver.push("1.5"):false;  
([].indexOf && [].forEach)?JS_ver.push("1.6"):false;  
((function(){try {[a,b] = [0,1];return true;}catch(ex) {return false;}})())?JS_ver.push("1.7"):false;  
([].reduce && [].reduceRight && JSON)?JS_ver.push("1.8"):false;  
("".trimLeft)?JS_ver.push("1.8.1"):false;  
  
JS_ver.supports = function()  
{  
    if (arguments[0])  
        return (!!~this.join().indexOf(arguments[0] +",") +",");  
    else  
        return (this[this.length-1]);  
}  
  
alert("Latest Javascript version supported: "+ JS_ver.supports());  
alert("Support for version 1.7 : "+ JS_ver.supports("1.7"));  

5. window.name for simple session handling 使用window.name进行简单会话处理

This one is something I really like. You can assign values as a string for window.name property and it preserves the values until you close the tab or window.

Although I’m not providing any script, I strongly suggest you to take full advantage from it. For instance, it’s very useful for toggling between debugging and (perfomance) testing modes, when building a website or an application.

这个是我真的喜欢的东西。您可以为指定一个字符串作为window.name属性的值,直到您关闭该标签或窗口。虽然我没有提供任何脚本,但我强烈建议您如充分利用这个方法。举例来说,在建设一个网站或应用程序的时候,在调试和测试模式之间切换是非常有用的。

6. Testing existence of property 判断属性是否存在

This issue can be approached at least from two directions. Either we check whether property exists or we check the type of property. But always avoid these small mistakes:

这个问题包含两个方面,既有检查属性时候存在,还要获取属性的类型。但我们总是忽略了这些小事情:

// BAD: This will cause an error in code when foo is undefined  
if (foo) {  
    doSomething();  
}   
  
// GOOD: This doesn't cause any errors. However, even when  
// foo is set to NULL or false, the condition validates as true  
if (typeof foo != "undefined") {  
    doSomething();  
}  
  
// BETTER: This doesn't cause any errors and in addition  
// values NULL or false won't validate as true  
if (window.foo) {  
    doSomething();  
}  

However, there may be situations, when we have deeper structure and proper checking would look like this:

但是,有的情况下,我们有更深的结构和需要更合适的检查的时候,可以这样:

// UGLY: we have to proof existence of every  
// object before we can be sure property actually exists  
if (window.oFoo && oFoo.oBar && oFoo.oBar.baz) {  
    doSomething();  
}  

7. Passing arguments for function 给函数传递参数

When function has both required and optional parameters (arguments), eventually we may end up with functions and function calls looking like this:

当函数既有必选又有可选参数的时候,我们可能是这样做的:

function doSomething(arg0, arg1, arg2, arg3, arg4) {  
...  
}  
  
doSomething('', 'foo', 5, [], false);  

It’s always easier to pass only one object instead of several arguments:

而传递一个对象总是比传递一堆的参数更方便:

function doSomething() {  
    // Leaves the function if nothing is passed  
    if (!arguments[0]) {  
        return false;  
    }  
  
    var oArgs   = arguments[0]  
        arg0    = oArgs.arg0 || "",  
        arg1    = oArgs.arg1 || "",  
        arg2    = oArgs.arg2 || 0,  
        arg3    = oArgs.arg3 || [],  
        arg4    = oArgs.arg4 || false;  
}  
  
doSomething({  
    arg1    : "foo",  
    arg2    : 5,  
    arg4    : false  
});  

This is only a rough example of passing an object as an argument. For instance, we could declare an object with name of the variable as keys and default values as properties (and/or data types).

这只是一个把对象作为参数传递的一个很简单的例子,例如,我们还可以声明一个对象,变量名作为Key,默认值作为Value。

8. Using document.createDocumentFragment()

You may need to dynamically append multiple elements into document. However, appending them directly into document will fire redrawing of whole view every time, which causes perfomance penalty. Instead, you should use document fragments, which are appended only once after completion:

您可能需要动态地追加多个元素到文档中。然而,直接将它们插入到文档中会导致这个文档每次都需要重新布局一个,相反的,你应该使用文档碎片,建成后只追加一次:

function createList() {  
    var aLI = ["first item", "second item", "third item",  
        "fourth item", "fith item"];  
  
    // Creates the fragment  
    var oFrag   = document.createDocumentFragment();  
  
    while (aLI.length) {  
        var oLI = document.createElement("li");  
  
        // Removes the first item from array and appends it  
        // as a text node to LI element  
        oLI.appendChild(document.createTextNode(aLI.shift()));  
        oFrag.appendChild(oLI);  
    }  
  
    document.getElementById('myUL').appendChild(oFrag);  
}  

9. Passing a function for replace() method 为replace()方法传递一个函数

There are situations when you want to replace specific parts of the string with specific values. The best way of doing this would be passing a separate function for method String.replace().

Following example is a rough implementation of making a more verbose output from a single deal in online poker:

有的时候你想替换字符串的某个部分为其它的值,最好的方法就是给String.replace()传递一个独立的函数。下面是实现在线扑克游戏中大量输出的一个简单例子:

var sFlop   = "Flop: [Ah] [Ks] [7c]";  
var aValues = {"A":"Ace","K":"King",7:"Seven"};  
var aSuits  = {"h":"Hearts","s":"Spades",  
            "d":"Diamonds","c":"Clubs"};  
  
sFlop   = sFlop.replace(/\[\w+\]/gi, function(match) {  
    match   = match.replace(match[2], aSuits[match[2]]);  
    match   = match.replace(match[1], aValues[match[1]] +" of ");  
  
    return match;  
});  
  
// string sFlop now contains:  
// "Flop: [Ace of Hearts] [King of Spades] [Seven of Clubs]"  

10. Labeling of loops (iterations) 循环中标签的使用

Sometimes, you may have iterations inside iterations and you may want to exit between looping. This can be done by labeling:

有的时候,循环中又嵌套了循环,你可能想在循环中退出,则可以用标签:

outerloop:  
for (var iI=0;iI<5;iI++) {  
    if (somethingIsTrue()) {  
        // Breaks the outer loop iteration  
        break outerloop;  
    }  
  
    innerloop:  
    for (var iA=0;iA<5;iA++) {  
        if (somethingElseIsTrue()) {  
            // Breaks the inner loop iteration  
            break innerloop;  
        }  
  
    }  
}  

Afterwords

Go ahead and comment! Did you learn anything new? Do you have good tips to share? I'm always delighted for sharing information about all the little details in Javascript.

And if you want to familiarize with Javascript irregularities, I suggest you visiting at wtfjs :).

本文地址:http://www.nowamagic.net/librarys/veda/detail/460,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/460

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《大话数据结构》 程杰 (作者)

《大话数据结构》主要内容包含:数据结构介绍、算法推导大O阶的方法;顺序结构与链式结构差异、栈与队列的应用;串的朴素模式匹配、KMP模式匹配算法;二叉树前中后序遍历、赫夫曼树及应用;图的深度、广度遍历;最小生成树两种算法、最短路径两种算法;拓扑排序与关键路径算法;折半查找、插值查找、斐波那契查找等静态查找;稠密索引、分块索引、倒排索引等索引技术;二叉排序树、平衡二叉树等动态查找;B树、B+树技术,散列表技术;冒泡、选择、插入等简单排序;希尔、堆、归并、快速等改进排序。

更多计算机宝库...