整理JavaScript方面的一些技巧。比較有用的函数,常见功能实现方法,仅作參考
//edit http://www.lai18.com 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
可是转换日期(new Date(myVar))和正則表達式(new RegExp(myVar))必须使用构造函数,创建正則表達式的时候要使用/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" => 255 parseInt(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 !@*/false;
这样一句简单的话就能够推断是否为ie,太。。
。
事实上还有很多其它妙的方法,请看以下
//edit http://www.lai18.com // 貌似是最短的,利用IE不支持标准的ECMAscript中数组末逗号忽略的机制 var ie = !-[1,]; // 利用了IE的条件凝视 var ie = /*@cc_on!@*/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;imax){ 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代码例如以下
Great Web resources
- Opera Web Standards Curriculum
- Sitepoint
- A List Apart
- YUI Blog
- Blame it on the voices
- Oddly specific
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
利用事件委派能够写出更加优雅的:
(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 = '', 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 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(); }
有的情况下,我们有更深的结构和须要更合适的检查的时候
// 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(); }
事实上最好的检測一个属性是否存在的方法为:
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中的正則表達式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属性
53JavaScriptkeywordreturn的使用方法
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秘密花园]对象其二:原型