日期:2014-05-16  浏览次数:20303 次

javascript 高级技巧

1:高级函数

?

?

1.1 作用域安全的构造函数

function Person(name,age,job){
	this.name=name;
	this.age=age;
	this.job=job;
}

var person=Person("Nicholas",29,"Software Engineer");
alert(window.name); //"Nicholas"
alert(window.age);  //29
alert(window.job);  //Software Engineer
/**
 *因为构造函数是作为普通函数调用的,忽略了new操作符。这个问题是由this对象的晚绑定造成的,在这里this被解析成了window对象。
 * window 的name属性是用于识别链接目标和框架的,所以这里对该属性的偶然覆盖可能会导致该页面上出现其他错误。
 * 这个问题的解决方法就是创建一个作用域安全的构造函数。 
 */
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);
	}
}
var person1=Person("Nicholas",29,"Software Engineer");
alert(window.name); //""
alert(person1.name); //"Nicholas"

var person2=Person("Shelby",34,"Ergonomist");
alert(person2.name); //"Shelby";


/**
 *如果使用构造函数窃取模式的继承且不使用原型链,那么这个继承很可能被破坏。0 
 */
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); //undefined


/**
 * 如果构造函数窃取结合使用原型链或者寄生组合则可以解决这个问题。 
 */
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;
	}
}

Rectangle.prototype=new Polygon();

var rect=new Rectangle(5,10);
alert(rect.sides); 

?

?

1.2:惰性载入函数

/**
 * 惰性载入函数 
 * 
 * 每次调用createXHR()的时候,它都要对浏览器所支持的能力仔细检查。首先检查内置的XHR,然后测试有没有基于ActiveX的XHR,
 * 最后如果都没有发现的话就抛出一个错误。每次调用 该函数都是这样,即使每次调用时分去的结果都不变。
 */
function createXHR(){
	if(typeof XMLHttpRequest !="undefined"){
		return new XMLHttpRequest();
	}else if(typeof ActiveXObject != "undefined"){
		if(typeof arguments.call.activeXString != "string"){
			var versions=["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"];
			
			for(var i=0,len=versions.length;i<len;i++){
				try{
					new ActiveXObject(version[i]);
					arguments.callee.activeXString=versions[i];
					break;
				}catch(ex){
					//跳过
				}
			}
		}
		
		return new ActiveXObject(arguments.callee.activeXString);
	}else{
		throw new Error("No XHR object available.");
	}
}


/**
 *解决方案就是称之为惰性载入的技巧。
 * 惰性载入表示函数执行的分支仅会发生1次:即函数第一次调用的时候。 在第一次调用 的过程中,
 * 该函数会被覆盖为另一个按合适方式执行的函数,这样任何对原函数的调用都不用再经过执行的分支了。 
 */

function createXHR() {
	if( typeof XMLHttpRequest != "undefined") {
		createXHR = function() {
			return new XMLHttpRequest();
		}
	} else if( typeof ActiveXObject != "undefined") {
		createXHR = function() {
			if( typeof arguments.call.activeXString != "string") {
				var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"];

				for(var i = 0, len = versions.length; i < len; i++) {
					try {
						new ActiveXObject(version[i]);
						arguments.callee.activeXString = versions[i];
						break;
					} catch(ex) {
						//跳过
					}
				}
			}

			return new ActiveXObject(arguments.callee.activeXString);
		}
	} else {
		createXHR=function(){
			throw new Error("No XHR object available.");
		}
	}
}

?

?

1.3:函数绑定

/**
 * 函数绑定
 * 
 * 函数绑定要创建一个函数,可以在特定环境中以指定参数调用另一个函数。该技巧常常和回调函数与事件处理程序一起使用。
 * 以将函数作为变量传递的同时保留代码执行环境。 
 */

/**
 * 执行事件时,显示的是undefined。这个问题在于没有保存handler.handleClick()的环境。 
 *