十個神奇的JavaScript技巧

來源:互聯網
上載者:User

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))和Regex(new RegExp(myVar))必須使用建構函式,而且建立Regex的時候要使用/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 :).

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.