Foward
关于JS函数的一些奇技淫巧,能够有效的提升网页性能。然而迟早会被新特性取代。
安全检测类型
通常做法
1
| var isArray = value instanceof Array;
|
利用Object原生方法,可以进行安全检测。至于什么个安全法。
1
| alert(Object.prototype.toString.call(value));
|
利用Object原生方法安全检测,几乎涵盖所有的数据类型
1 2 3 4 5 6 7 8 9 10 11
| function isArray(value){ return Object.prototype.toString.call(value) == "[object Array]"; } function isFunction(value){ return Object.prototype.toString.call(value) == "[object Function]"; } function isRegExp(value){ return Object.prototype.toString.call(value) == "[object RegExp]"; }
|
甚至支持原生JSON检测
1 2
| var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON) == "[object JSON]";
|
作用域安全的构造函数
1、防止丢失new关键词,而造成的window污染。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function Person(name, age, job){ this.name = name; this.age = age; this.job = job; } function Person(name, age, job){ if (this instanceof Person){ this.name = name; this.age = age; this.job = job; } else { return new Person(name, age, job); } }
|
2、继承链
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| function Polygon(sides){ if (this instanceof Polygon){ this.sides = sides; this.getArea = function(){ return 0; } } else { return new Polygon(sides); } } function Rectangle(width, height){ Polygon.call(this, 2); this.width = width; this.height = height; this.getArea = function(){ return this.width * this.height; } } var rect = new Rectangle(5, 10); alert(rect.sides); Rectangle.prototype = new Polygon(); var rect = new Rectangle(5, 10); alert(rect.sides);
|
关于原型链的问题,我们之后讨论。
惰性载入函数
利用var的函数技巧,来看一个跨浏览器创建XML请求的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| function createXHR(){ if (typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); } else if (typeof ActiveXObject != "undefined"){ if (typeof arguments.callee.activeXString != "string") { var version = ["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument"], i, len; for (i=0, len=version.length; i < len; i++){ try { new ActiveXObject(version[i]); arguments.callee.activeXString = version[i]; break; } catch(ex) { } } } return new ActiveXObject(arguments.callee.activeXString); } else { throw new Error("No HHR object available."); } }
|
对于每一次调用这个函数,都要进行冗长的条件判断,然而对于同一款浏览器的参数条件都是相同的,为了提升性能,我们可以对这个函数稍加改进。
第一种方法是第一次调用这个函数时根据条件处理指针,此后这个函数就无需进行if-else判断。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| function createXHR(){ if (typeof XMLHttpRequest != "undefined"){ createXHR = createXHR(){ return new XMLHttpRequest(); }; } else if (typeof ActiveXObject != "undefined"){ createXHR = createXHR(){ if (typeof arguments.callee.activeXString != "string") { var version = ["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument"], i, len; for (i=0, len=version.length; i < len; i++){ try { new ActiveXObject(version[i]); arguments.callee.activeXString = version[i]; break; } catch(ex) { } } } return new ActiveXObject(arguments.callee.activeXString); }; } else { createXHR = function(){ throw new Error("No HHR object available."); }; } }
|
我们也可以在载入时就指定这个函数,根据适用条件直接返回一个匿名函数,代价是函数初次载入时牺牲一些性能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| var createXHR = (function(){ if (typeof XMLHttpRequest != "undefined"){ return function(){ return new XMLHttpRequest(); }; } else if (typeof ActiveXObject != "undefined"){ return function(){ if (typeof arguments.callee.activeXString != "string") { var version = ["MSXML2.DOMDocument.6.0", "MSXML2.DOMDocument.3.0", "MSXML2.DOMDocument"], i, len; for (i=0, len=version.length; i < len; i++){ try { new ActiveXObject(version[i]); arguments.callee.activeXString = version[i]; break; } catch(ex) { } } } return new ActiveXObject(arguments.callee.activeXString); }; } else { return function(){ throw new Error("No HHR object available."); }; } })();
|
无论是哪一种方法,在调用此函数的时候都能够提升性能。
函数绑定
先举一个点击的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| var handler = { message: "Event handled", handleClick: function(event){ alert(this.message); } }; var btn = document.getElementById(my-btn); EventUtil.addHandler(btn, "click", handler.handleClick); EventUtil.addHandler(btn, "click", function(event){ handler.handleClick(event); });
|
待更