javascript代码复用模式-----传统继承

javascript是一门弱类型的语言,虽然是面向对象,但是没有类的概念。不过由于其强大的动态灵活性,我们可以模拟传统强类型语言的继承模式。

一、默认模式

最常用的的一种默认方法,prototype指向父类的一个对象。

			function Person(){
				this.name = 'zs';
			}
			Person.prototype.say = function(){
				alert('hello');
			}
			
			function Child(){				
			}
			Child.prototype = new Person();
			console.log(new Child().name);// 结果 zs
此模式会继承this和原型里面所有的属性,子类同名属性,会隐藏父类的。

缺点:this属性是访问原型获得的,并不是子类的自身属性,子类修改,则父类也会改变

二、借用模式

call、apply方法借用父类的构造函数,子类将有this属性副本,修改不会影响父类

			function Person(){
				this.name = 'zs';
			}
			Person.prototype.say = function(){
				console.log('hello');
			}
			
			function Child(){
				//借用父类构造函数,子类拥有属性副本
				Person.apply(this,arguments);
			}
			console.log(new Child().name);// 结果 zs
			new Child().say();// 结果  undefind

但此模式只能继承this属性,不能继承原型方法

三、借用模式+默认模式

			function Person(){
				this.name = 'zs';
			}
			Person.prototype.say = function(){
				console.log('hello');
			}
			
			function Child(){
				//借用父类构造函数,子类拥有属性副本
				Person.apply(this,arguments);
			}
			Child.prototype = new Person();
			console.log(new Child().name);// 结果 zs
			new Child().say();// 结果  hello
此模式拥有属性副本,并继承原型中的属性

缺点:有2套this属性,效率底下


四、共享原型模式

prototype指向父类原型

			function Person(){
				this.name = 'zs';
			}
			Person.prototype.say = function(){
				console.log('hello');
			}
			
			function Child(){
			}
			Child.prototype = Person.prototype;
			console.log(new Child().name);// undefined
			new Child().say();// 结果  hello
此模式子类和父类永享原型,只继承原型属性,不包括this属性

缺点:平级,子类修改原型,父类也会修改


五、临时构造函数模式(利用了原型继承的思想,下一篇博客会讲)

			function Person(){
				this.name = 'zs';
			}
			Person.prototype.say = function(){
				console.log('hello');
			}
			
			function Child(){
			}
			function f(){			
			}
			f.prototype = Person.prototype;		
			Child.prototype = new f();
			console.log(new Child().name);// 结果 undefined
			new Child().say();// 结果  hellow

此模式改进了共享模式的缺点。用了一个临时函数f来共享原型。并让子类继承。子类修改只会修改f的对象并不会修改原型。实际上是为子类提供了一个原型。

只继承原型属性。


注:临时构造函数模式 圣杯版(推荐)

		var inherit = function(){
			var fun = function(){}
			return function(c,p){
				fun.prototype = p.prototype;
				c.prototype = new fun();
				c.father = p.prototype;
				c.prototype.constructor = c;
			}
		}()

六、kclass 语法糖(完美模拟类式继承)

借用模式继承this属性

临时构造函数模式继承原型属性

约定构造函数名称

返回一个新构造函数

			var klass = function(Parent,props){
				var child,F,i;
				child = function(){
					//先调父类构造函数,再调子类构造函数
					if(child.father && child.father.hasOwnProperty("__construct")){
						child.father.__construct.apply(this,arguments);
					}
					if(child.prototype.hasOwnProperty("__construct")){
						child.prototype.__construct.apply(this,arguments);
					}
				}
				
				//临时构造函数模式   继承
				Parent = Parent || Object;
				F = function(){};
				F.prototype = Parent.prototype;
				child.father = Parent.prototype;
				child.prototype = new F();
				child.prototype.constructor = child;
				
				//添加实现方法
				for(i in props){
					if(props.hasOwnProperty(i)){
						child.prototype[i] = props[i];
					}
				}
				return child;
			}
			
			//测试
			var Man = klass(null,{
				__construct:function(what){
					console.log(("Man's constructor'"));
					this.name = what;
				},
				getName:function(){
					return this.name;
				}
			})
			
			var first = new Man('adam');
			console.log(first.getName()); //结果 adam;
			
			var SuperMan = klass(Man,{
				__construct:function(what){
					console.log(("SuperMan's constructor'"));
					this.name = what;
				},
				getName:function(){
					var name = SuperMan.father.getName.call(this);
					return "I am"+name;
				}
			})
			
			var clark = new SuperMan('clark kent');
			console.log(clark.getName());//结果  i am clark kent



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值