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

JavaScript----创建可重用代码
1.1、原型式继承
    JavaScript对象的创建与继承使用了一套特别的模式,称为原型式继承。这种方法的原理是,对象的构造函数可以从其他对象中继承方法,它创建出一个原型对象后,所有其他的新对象都可以基于这个原型对象来构建。
    整个过程都是通过原型属性(prototype)来实现的(这是每个函数都有的一个属性,用作构造函数的函数自然也会有这个属性)。原型式继承的设计适用于单继承而非多继承。原型本身并不会从其他原型或者构造函数中继承属性,而属性都是从实际对象那里继承过来的。例
<script>
//为Person对象创建一个构造函数
function Person(name){
	this.name = name;
}
//给Person对象添加一个新方法
Person.prototype.getName = function(){
	return this.name;
};
//创建一个User对象的构造函数
function User(name, password){
	//注意,这里并没有支持方便的重载/继承,也就是说,
	//不能调用父类的构造函数
	//此处等于是给父类的name属性赋值,类似于java的super(name);
	//this.name = name;  
	Person.call(this, name);//调用父类的构造函数
	this.password = password;
}
//User对象继承所有Person对象的方法
User.prototype = new Person();
//添加一个新方法到User对象中
User.prototype.getPassword = function(){
	return this.password;
};
var user = new User("张三", "123");
alert(user.name);
alert(user.getName());
alert(user.password);
alert(user.getPassword());
</script>

    上面这个例子中最重要的一行是User.prototype = new Person();。分析一下这究竟是什么意思:User是对User对象构造函数的引用。new Person()使用Person构造函数创建了一个新的Person对象,然后把User构造函数的原型置为这个操作的结果。也就是说,每当你new User()时,得到的新User对象都会带有Person对象的所有的方法,如同通过操作new Person()得到的一样。
1.2、类式继承
    JavaScript里模拟类式继承的3个函数:
<script>
//简单的辅助函数,让你可以将新函数绑定到对象的prototype上
//这个将会添加一个公共方法到 Function.prototype 中,
//这样通过类扩展所有的函数都可以用它了。它要一个名称和一个函数作为参数。
//它返回 this 。当我写一个没有返回值的方法时,
//我通常都会让它返回 this 。这样可以形成链式语句。
Function.prototype.method = function(name, func){
	this.prototype[name] = func;
	return this;
};

//一个(相当复杂的)函数,允许你方便地从其他对象继承函数,
//同时仍然可以调用属于父对象的那些函数
//inherits 方法,它会指出一个类是继承自另一个类的。
//它必须在两个类都定义完了之后才能定义,但要在方法继承之前调用。
Function.method('inherits', function(parent){
	//记录我们目前所在父层次的级数
	var depth = 0;
	//继承父对象的方法
	var proto = this.prototype = new prent();

	//创建一个新的名为'uber'的"特权"函数,
	//调用它时会执行所有在继承时被重写的函数
	this.method('uber', function uber(name){
		var func;	//要执行的函数
		var ret;	//函数的返回值
		var v = parent.prototype;	//父对象的prototype

		//如果我们已经在某个'uber'函数之内
		if(depth){
			//上溯必要的depth,以找到原始的prototype
			for(var i = d; i > 0; i += 1){
				v = v.constructor.prototype;
			}

			//从该prototype中获得函数
			func = v[name];
		//否则这就是'uber'函数的第一次调用
		} else {
			//从prototype获得要执行的函数
			func = proto[name];

			//如果此函数属于当前的prototype
			if(func == this[name]){
				//则改为调用父对象的prototype
				func = v[name];
			}
		}

		//记录我们在继承堆栈中所在位置的级数
		depth += 1;

		//使用除第一个以外所有的arguments调用此函数。
		//(因为第一个参数是执行的函数名)
		ret = func.apply(this, Array.prototype.slice.apply(arguments, [1]));
		//恢复继承堆栈
		depth -= 1;
		//返回执行过的函数的返回值
		return ret;
	});
	return this;
});

//只继承父对象特定函数的函数。而非使用new parent()继承所有的函数
//swiss 方法对每个参数进行循环。每个名称,它都将 parent的原型中
//的成员复制下来到新的类的 prototype 中。
Function.method('swiss', function(parent){
	//遍历所有要继承的方法
	for(var i = 1; i < arguments.length; i += 1){
		//需要导入的方法名
		var name = arguments[i];
		//将此方法导入this对象的prototype中
		this.prototype[name] = parent.prototype[name];
	}
	return this;
});
</script>

    这三个函数到底提供了什么?
    Function.prototype.method:它提供了一个简单的方法,把函数与构造函数的原型关联起来。之所以有效,是因为所有的构造函数本身都是函数,所以能获得“method”这个新方法。
    Function.prototype.inherits:这一函数可以用于提供简单的单对象继承,它的代码主要围绕在任意对象方法中调用this.uber('methodName')为中心,并在这个uber方法去执行它要覆盖的父对象的方法。这是JavaScript继承模型中并未内建的部分。
    Function.prototype.swiss:这是.method()函数的增强版,可以用于从单一父对象获取多个函数。如果用在多个父对象上就能获得可用的多对象继承。
使用类式继承风格的JavaScript函数例子:
<script>
//创建一个新的Person对象构造函数
function Person(name){
	this.name = name;
}
//给Person对象添加一个新的方法
Person.method('getName', function(){
	return this.name;
});
var per = new Person("张三");
alert(per.getName());

//创建了一个新的User对象构造函数
function User(name, password){
	this.name = name;
	this.password = password;
}
//从Person对象继承所有的方法
User.inherits(Person);
//给User对象添加一个新的方法
User.method('