javascript中类的定义和继承


类的定义

类定义有三种基本方法,

创建并能返回特定类型的对象的函数(工厂函数),例如:function Co(){ var o = new Object; o.a = 1 return o}; 用这种方式创建对象: var o = Co()
创建构造函数,用new 实例化,例如 function Co(){this.a = 1} 用这种方式创建对象:var o = new Co()
原型方式,利用对象的prototype属性,例如 function Co(){}; Co.prototype.a = 1; 用这种方式创建对象: var o = new Co()
可灵活运用这三种方式进行组合

类的继承

类的继承有两种基本方法

对象冒充 基本原理: 构造函数使用this关键字给所有属性和方法赋值(构造函数实际上仅仅是赋值函数),所以可以利用一种方式,在类内部直接运行赋值函数,把其this关键字传递给新类。例如:


var a = function(){
	this.a = 1;
	this.b = 2;
	alert(this);
}

var b = function(){
	this.aa = a;//对a中的this进行转换,同样的方式还有
	this.aa();
	delete this.aa;  //要把这个中间方法删除掉,否则可能会在以后的操作中覆盖原来类的方法

	//或者
	a.call(this,arg1,arg2);
	//或者
	a.apply(this,[args]);
}

var ob = new b();	


原型链

基本原理:关于原型链,详见(http://www.iteye.com/topic/53537)把超类的一个实例付给子类的prototype对象,即可把超类的固定属性和方法传递给子类,要注意一点,这种方法无法在实例化时传递参数,所以一般采用混合方式进行类的继承。

prototype.js中的类定义和继承

1.6.0以前:

/** obsolete syntax **/ 
var Person = Class.create();    //通过Class.create方法创建空类
Person.prototype = {               //把方法定义到prototype中,注意,是通过initalize方法初始化类的属性
  initialize: function(name) { 
    this.name = name; 
  }, 
  say: function(message) { 
    return this.name + ': ' + message; 
  } 
}; 

var guy = new Person('Miro'); 
guy.say('hi'); 
// -> "Miro: hi" 
                                            //prototype中的继承方式:
var Pirate = Class.create();    //建立空类;
// inherit from Person class: 
Pirate.prototype = Object.extend(new Person(), {    //先实例化超类,再把超类中的方法复制到子类中去,
  // redefine the speak method                               //注意,实际上prototype类定义机制中并没有直接定义
say: function(message) {                                       //类的属性而是通过intilize方法,而且所有的方法都
    return this.name + ': ' + message + ', yarr!';      //之直接定义在prototype中,所以直接用原型链方式
  }                                                                        //继承超类的所有方法不会产生问题。
}); 

var john = new Pirate('Long John'); 
john.say('ahoy matey'); 
// -> "Long John: ahoy matey, yarr!"



来看一下Class.create方法的实现代码


var Class = {
  create: function() {
    return function() {                                          //实际上把所有的属性定义到intiliaze方法(实际上是一个类)中,
      this.initialize.apply(this, arguments);              //然后通过对象冒充方式继承该类
    }
  }
}			


可以从prototype的例子充分体会到通过对象冒充和原型链类继承的差别,一般来说属性需用对象冒充方式继承,方法需用原型链方式继承。

prototype-1.6.0以后版本:

1.6.0以后,对prototype的类进行了更多的扩展,举例:	

/** new, preferred syntax **/ 
// properties are directly passed to `create` method 
var Person = Class.create({ 
  initialize: function(name) {                       //不必定义一个空类,and定义方法的位置改变
    this.name = name; 
  }, 
  say: function(message) { 
    return this.name + ': ' + message; 
  } 
}); 

// when subclassing, specify the class you want to inherit from 
var Pirate = Class.create(Person, {            //第一个参数是class,作为超类在定义类时直接继承
  // redefine the speak method 
say: function($super, message) { 
    return $super(message) + ', yarr!'; 
  } 
}); 

var john = new Pirate('Long John'); 
john.say('ahoy matey'); 
// -> "Long John: ahoy matey, yarr!"



//声明子类时对子类的initialize进行重写

1.60以前

var Animal = Class.create(); 
Animal.prototype = { 
  initialize: function(name, sound) {                                 //超类,顶一个两个参数
    this.name = name; 
    this.sound = sound; 
  }, 	          

speak: function() { 
alert(name + " says: " + sound + "!"); 
} 
}; 

var snake = new Animal("Ringneck", "hissssssssss"); 
snake.speak(); 
// -> alerts "Ringneck says: hissssssssss!" 

var Dog = Class.create(); 

Dog.prototype = Object.extend(new Animal(), { 
initialize: function(name) { //子类,定义一个参数
this.name = name; 
this.sound = "woof"; 
} 
}); 

var fido = new Dog("Fido"); 
fido.speak(); 
// -> alerts "Fido says: woof!"	

1.60以后

var Animal = Class.create({ 
  initialize: function(name, sound) { 
    this.name = name; 
    this.sound = sound; 
  }, 
	      

speak: function() { 
alert(this.name + " says: " + this.sound + "!"); 
} 
}); 
// subclassing Animal 
var Snake = Class.create(Animal, { 
initialize: function($super, name) { //通过$super的方式调用超类的initliaze, 
$super(name, 'hissssssssss'); 
} 
}); 
var ringneck = new Snake("Ringneck"); 
ringneck.speak(); 
//-> alerts "Ringneck says: hissssssssss!" 

var rattlesnake = new Snake("Rattler"); 
rattlesnake.speak(); 
//-> alerts "Rattler says: hissssssssss!" 

// mixing-in Enumerable 
var AnimalPen = Class.create(Enumerable, { 
initialize: function() { 
var args = $A(arguments); 
if (!args.all( function(arg) { return arg instanceof Animal })) 
throw "Only animals in here!"
this.animals = args; 
}, 

// implement _each to use Enumerable methods 
_each: function(iterator) { 
return this.animals._each(iterator); 
} 
});
var snakePen = new AnimalPen(ringneck, rattlesnake); 
snakePen.invoke('speak'); 
//-> alerts "Ringneck says: hissssssssss!" 
//-> alerts "Rattler says: hissssssssss!" 
		 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值