一直反复地再研究这个东西,还是简单地记录一下。
其实很多面向对象的语言必须支持继承机制。即一个类能够重用(继承)另一个类的方法和属性。这样的话就会有一个“基类”
注意:一般出于安全,本地类和宿主类不能作为基类。
创建的子类将会继承基类的所有属性和方法,包括构造函数和方法的实现。这些属性和方法多少公用的,子类还可以添加基类中没有的新的私有的属性和方法,当然也可以覆盖基类中的属性和方法。
关于继承的方式很多比如: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处理
验证:ITDesigner.prototype = People.prototype; //2012-12-4 发现单纯采用这样方式,继承无效!!!!!!!!!!!
//先来看一种不合适的处理方式 //它的缺点就是会改变父类的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是不区分本地私有属性和原型链上的公用属性