標籤:
整理JavaScript方面的一些技巧,比較實用的函數,常見功能實現方法,僅作參考
變數轉換
//edit http://www.lai18.com var myVar = "3.14159",str = ""+ myVar,// to stringint = ~~myVar, // to integerfloat = 1*myVar, // to floatbool = !!myVar, /* to boolean - any string with lengthand any number except 0 are true */array = [myVar]; // to array
但是轉換日期(new Date(myVar))和Regex(new RegExp(myVar))必須使用建構函式,建立Regex的時候要使用/pattern/flags這樣的簡化形式。
取整同時轉換成數值型
//edit http://www.lai18.com //字元型變數參與運算時,JS會自動將其轉換為數值型(如果無法轉化,變為NaN) ‘10.567890‘ | 0 //結果: 10 //JS裡面的所有數值型都是雙精確度浮點數,因此,JS在進行位元運算時,會首先將這些數字運算數轉換為整數,然後再執行運算 //| 是二進位或, x|0 永遠等於x;^為異或,同0異1,所以 x^0 還是永遠等於x;至於~是按位取反,搞了兩次以後值當然是一樣的 ‘10.567890‘ ^ 0 //結果: 10 - 2.23456789 | 0 //結果: -2 ~~-2.23456789 //結果: -2
日期轉數值
//JS本身時間的內部表示形式就是Unix時間戳記,以毫秒為單位記錄著當前距離1970年1月1日0點的時間單位 var d = +new Date(); //1295698416792
類數組對象轉數組
var arr =[].slice.call(arguments)
下面的執行個體用的更絕
function test() { var res = [‘item1‘, ‘item2‘] res = res.concat(Array.prototype.slice.call(arguments)) //方法1 Array.prototype.push.apply(res, arguments) //方法2}
進位之間的轉換
(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" => 255parseInt(string,8) // converts octal to int, eg. "20" => 16
將一個數組插入另一個數組指定的位置
var a = [1,2,3,7,8,9];var b = [4,5,6];var insertIndex = 3;a.splice.apply(a, Array.prototype.concat(insertIndex, 0, b));
刪除數組元素
var a = [1,2,3,4,5];a.splice(3,1); //a = [1,2,3,5]
大家也許會想為什麼要用splice而不用delete,因為用delete將會在數組裡留下一個空洞,而且後面的下標也並沒有遞減。
判斷是否為IE
var ie = /*@cc_on [email protected]*/false;
這樣一句簡單的話就可以判斷是否為ie,太。。。
其實還有更多妙的方法,請看下面
//edit http://www.lai18.com // 貌似是最短的,利用IE不支援標準的ECMAscript中數組末逗號忽略的機制var ie = !-[1,];// 利用了IE的條件注釋var ie = /*@[email protected]*/false;// 還是條件注釋var ie//@cc_on=1;// IE不支援垂直定位字元var ie = ‘\v‘==‘v‘;// 原理同上var ie = !+"\v1";
學到這個瞬間覺得自己弱爆了。
盡量利用原生方法
要找一組數字中的最大數,我們可能會寫一個迴圈,例如:
var numbers = [3,342,23,22,124];var max = 0;for(var i=0;i<numbers.length;i++){ if(numbers[i] > max){ max = numbers[i]; }}alert(max);
其實利用原生的方法,可以更簡單實現
var numbers = [3,342,23,22,124];numbers.sort(function(a,b){return b - a});alert(numbers[0]);
當然最簡潔的方法便是:
Math.max(12,123,3,2,433,4); // returns 433
當前也可以這樣
Math.max.apply(Math, [12, 123, 3, 2, 433, 4]) //取最大值Math.min.apply(Math, [12, 123, 3, 2, 433, 4]) //取最小值
產生隨機數
Math.random().toString(16).substring(2);// toString() 函數的參數為基底,範圍為2~36。 Math.random().toString(36).substring(2);
不用第三方變數交換兩個變數的值
a=[b, b=a][0];
事件委派
舉個簡單的例子:html代碼如下
<h2>Great Web resources</h2><ul id="resources"> <li><a href="http://opera.com/wsc">Opera Web Standards Curriculum</a></li> <li><a href="http://sitepoint.com">Sitepoint</a></li> <li><a href="http://alistapart.com">A List Apart</a></li> <li><a href="http://yuiblog.com">YUI Blog</a></li> <li><a href="http://blameitonthevoices.com">Blame it on the voices</a></li> <li><a href="http://oddlyspecific.com">Oddly specific</a></li></ul>
js代碼如下:
// Classic event handling example(function(){ var resources = document.getElementById(‘resources‘); var links = resources.getElementsByTagName(‘a‘); var all = links.length; for(var i=0;i<all;i++){ // Attach a listener to each link links[i].addEventListener(‘click‘,handler,false); }; function handler(e){ var x = e.target; // Get the link that was clicked alert(x); e.preventDefault(); };})();
利用事件委派可以寫出更加優雅的:
(function(){ var resources = document.getElementById(‘resources‘); resources.addEventListener(‘click‘,handler,false); function handler(e){ var x = e.target; // get the link tha if(x.nodeName.toLowerCase() === ‘a‘){ alert(‘Event delegation:‘ + x); e.preventDefault(); } };})();
檢測ie版本
var _IE = (function(){ var v = 3, div = document.createElement(‘div‘), all = div.getElementsByTagName(‘i‘); while ( div.innerHTML = ‘<!--[if gt IE ‘ + (++v) + ‘]><i></i><![endif]-->‘, all[0] ); return v > 4 ? v : false ;}());
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"));
判斷屬性是否存在
// BAD: This will cause an error in code when foo is undefinedif (foo) { doSomething();}// GOOD: This doesn‘t cause any errors. However, even when// foo is set to NULL or false, the condition validates as trueif (typeof foo != "undefined") { doSomething();}// BETTER: This doesn‘t cause any errors and in addition// values NULL or false won‘t validate as trueif (window.foo) { doSomething();}
有的情況下,我們有更深的結構和需要更合適的檢查的時候
// UGLY: we have to proof existence of every// object before we can be sure property actually existsif (window.oFoo && oFoo.oBar && oFoo.oBar.baz) { doSomething();}
其實最好的檢測一個屬性是否存在的方法為:
if("opera" in window){ console.log("OPERA");}else{ console.log("NOT OPERA");}
檢測對象是否為數組
var obj=[];Object.prototype.toString.call(obj)=="[object Array]";
給函數傳遞對象
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});
為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]"
迴圈中使用標籤
有時候迴圈當中嵌套迴圈,你可能想要退出某一層迴圈,之前總是用一個標誌變數來判斷,現在才知道有更好的方法
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; } }}
對數組進行去重
/**@desc:對數組進行去重操作,返回一個沒有重複元素的新數組*/function unique(target) { var result = []; loop: for (var i = 0, n = target.length; i < n; i++) { for (var x = i + 1; x < n; x++) { if (target[x] === target[i]) { continue loop; } } result.push(target[i]); } return result;}
或者如下:
Array.prototype.distinct = function () { var newArr = [],obj = {}; for(var i=0, len = this.length; i < len; i++){ if(!obj[typeof(this[i]) + this[i]]){ newArr.push(this[i]); obj[typeof(this[i]) + this[i]] = ‘new‘; } } return newArr;}
其實最優的方法是這樣的
Array.prototype.distinct = function () { var sameObj = function(a, b){ var tag = true; if(!a || !b) return false; for(var x in a){ if(!b[x]) return false; if(typeof(a[x]) === ‘object‘){ tag = sameObj(a[x],b[x]); } else { if(a[x]!==b[x]) return false; } } return tag; } var newArr = [], obj = {}; for(var i = 0, len = this.length; i < len; i++){ if(!sameObj(obj[typeof(this[i]) + this[i]], this[i])){ newArr.push(this[i]); obj[typeof(this[i]) + this[i]] = this[i]; } } return newArr; }
使用範例(借用評論):
var arr=[{name:"tom",age:12},{name:"lily",age:22},{name:"lilei",age:12}];var newArr=arr.distinct(function(ele){ return ele.age;});
尋找字串中出現最多的字元及個數
var i, len, maxobj=‘‘, maxnum=0, obj={};var arr = "sdjksfssscfssdd";for(i = 0, len = arr.length; i < len; i++){ obj[arr[i]] ? obj[arr[i]]++ : obj[arr[i]] = 1; if(maxnum < obj[arr[i]]){ maxnum = obj[arr[i]]; maxobj = arr[i]; }}alert(maxobj + "在數組中出現了" + maxnum + "次");
其實還有很多,這些只是我閑來無事總結的一些罷了。
更多JavaScript學習整理參考:
1正則總結:JavaScript中的Regex
2JavaScript中變數的類型
3深入知曉JavaScript的範圍問題
4JavaScript探秘:for迴圈(for Loops)
5JavaScript探秘:for-in迴圈(for-in Loops)
6JavaScript探秘:Prototypes強大過頭了
7JavaScript探秘:var預解析與副作用
8JavaScript探秘:謹慎使用全域變數
9JavaScript探秘:編寫可維護的代碼的重要性
10我們應該如何去瞭解JavaScript引擎的工作原理
11JavaScript探秘:命名函數運算式
12JavaScript探秘:調試器中的函數名
13JavaScript探秘:JScript的記憶體管理
14JavaScript探秘:函式宣告與函數運算式
15JavaScript探秘:JScript的Bug
16JavaScript探秘:eval()是“魔鬼”
17JavaScript探秘:基本編碼規範
18JavaScript探秘:用parseInt()進行數值轉換
19JavaScript探秘:建構函式 Constructor
20執行內容其一:變數對象與使用中的物件
21JavaScript探秘:原型鏈 Prototype chain
22執行內容其二:範圍鏈 Scope Chains
23JavaScript探秘:對象Object
24JavaScript探秘:SpiderMonkey的怪癖
25JavaScript探秘:命名函數運算式替代方案
26JavaScript函數其二:函數運算式
27JavaScript函數其四:函數構造器
28JavaScript函數其一:函式宣告
29JavaScript函數其三:分組中的函數運算式
30JavaScript探秘:強大的原型和原型鏈
31執行內容其四:This指標
32執行內容其三:閉包 Closures
33JavaScript變數對象其三:執行內容的兩個階段
34JavaScript變數對象其二:VO在不同的執行內容中
35JavaScript變數對象其四:關於變數
36JavaScript變數對象其一:VO的聲明
37JavaScript變數對象其五:__parent__ 屬性
38JavaScript範圍鏈其三:範圍鏈特徵
39JavaScript範圍鏈其二:函數的生命週期
40JavaScript範圍鏈其一:範圍鏈定義
41JavaScript閉包其二:閉包的實現
42JavaScript閉包其一:閉包概論
43JavaScript閉包其三:閉包的用法
44JavaScript對象的訪問與遍曆
45JavaScript的變數預解析特性
46新的JavaScript資料結構Streams
47談談Javascript的匿名函數
48簡述JavaScript的類與對象
49JavaScript定義類與對象的一些方法
50建立JavaScript的雜湊表Hashtable
51JavaScript閉包的特性
52談談JavaScript的prototype屬性
53JavaScript關鍵字return的用法
54JavaScript是如何?繼承的
55理清一下JavaScript物件導向思路
56深入JavaScript對象建立的細節
57探討JavaScript的事件冒泡
58你瞭解JavaScript非阻塞載入指令碼嗎
59JavaScript Date的原型方法擴充
60JavaScript prototype背後的工作原理
61一篇博文將JavaScript盡收眼底
62深入淺出JavaScript變數範圍
63閑話JavaScript與Cookies
64一個JavaScript反射使用的例子
65淺析JavaScript的記憶體回收機制
66非阻塞式JavaScript指令碼及延伸知識
67JavaScript中繼承機制的模仿實現
68JavaScript要理解閉包先瞭解詞法範圍
69深入研究JavaScript的事件機制
70理解JavaScript的function
71JavaScript對象學習筆記
72[JavaScript秘密花園]對象其一:使用和屬性
73[JavaScript秘密花園]對象其二:原型
JavaScript學習總結-技巧、實用函數、簡潔方法、編程細節