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

js--面向对象OOP之继承

一直反复地再研究这个东西,还是简单地记录一下。

?

其实很多面向对象的语言必须支持继承机制。即一个类能够重用(继承)另一个类的方法和属性。这样的话就会有一个“基类

注意:一般出于安全,本地类和宿主类不能作为基类

?

创建的子类将会继承基类的所有属性和方法,包括构造函数和方法的实现。这些属性和方法多少公用的,子类还可以添加基类中没有的新的私有的属性和方法,当然也可以覆盖基类中的属性和方法。

?

关于继承的方式很多比如:call,apply,还有“对象冒充”,prototype,"混合模式"等等。

?

?

//父类
function People(){
   this.species ="人类";
}

?

?

?

//it子类
function ITDesigner(name,age){
     this.name = name;
     this.age = age;
}

?

?1.我用apply处理

?

ps:apply和call的区别其实很简单:apply的第二个参数必须是参数的数组,call的是可以是字符串,也可以是多个

?

function ITDesigner(name,age){
    //在子类内部调用apply
   People.apply(this,arguments);
   this.name = name;
   this.age = age;
}

?

var zhang = new ITDesigner("zhang",24);console.log(zhang.species); //人类
?

2.再用prototype处理

?

?

//先来看一种不合适的处理方式
//它的缺点就是会改变父类的constructor
//什么是constructor----prototype对象多有constructor属性,指向它的构造函数
ITDesigner.prototype = People.prototype;
ITDesigner.prototype.constructor = ITDesigner;
var zhang1 = new ITDesigner("zhang1",24);
console.log(zhang1.species);           //人类
//注意这里
console.log(People.prototype.constructor); //ITDesigner 

?ps:当然如果你把

?

//ITDesigner.prototype = People.prototype
//换成实例化
ITDesigner.prototype = new People();
//没有变构造函数哦
console.log(People.prototype.constructor) //People

?3.试试封装函数

?

//思路还是定义一个空对象做中介
//至少空对象比实例化对内存上友好一点

//参数说明
//Child---子类名
//Parent ---父类名
function extend(Child,Parent){
      var D = function(){};
      D.prototype = Parent.prototype;
      Child.prototype = new D();
      Child.prototype.constructor = Child;
}

//调用
extend(ITDesigner,People);
var zhang2 = new ITDesigner("zhang2",24);
console.log(zhang2.species);     //人类
console.log(People.prototype.constructor); //People

?ps:是不是有点YUI的影子

?

前段由于工作需要,一种在研究tangram,其实里面的fx部分也有定义基类

?

放一个自己的脚本库的object API

?

/*
*extend-copy the source's properties into target*
*@function*
*@param {Object} target*
*@param {Object} source*
*@return {Object}*
*@remark--it will cover the target's properties when the key is same in source*
*source's prototype is not copy*
*/
ZYC.object.extend = function(target,source){
    for(var key in source){
       if(source.hasOwnProperty(key)){
	      target[key] = source[key];
	   }
	}
	return target;
};

?

ps:我的object的脚本库的extend是用的hasOwnPrototype,所以原型链的属性是不支持复制的,如果你有需求可以改成in,如下方:

?

?

?看到这个你是不是想,上面的继承的extend还可以这样写

?

//重写的
function extend(Child,Parent){
    var Cp =Child.prototype; 
    var Pp =Parent.prototype;
    for(var i in Pp){
        Cp[i] = Pp[i];
   }  
}

?ps:这里的in是不区分本地私有属性和原型链上的公用属性