原型链继承:
//原型链继承:把父类的私有+公有的属性和方法,都作为子类公有的属性; //核心:不是把父类私有+公有的属性克隆一份一模一样的给子类的公有吧;他是通过__proto__建立和子类之间的原型链,当子类的实例需要使用父类的属性和方法的时候,可以通过__proto__一级级找上去使用; function F(){//父类; this.x=100; this.y=300; } F.prototype.showX=function(){ alert(123); }; function S(){//子类; this.y=200; } S.prototype=new F;//子类公有方法上继承父类私有+公有的属性 S.prototype.constructor=S;//添加子类constructor指向 var p1=new S; var p2=new S; console.dir(p1) /* * 私有属性:y:200 * __proto__: * constructor:S; * x:100; * __proto__: * constructor:F; * showX:function(){} * * * */ //p1.__proto__.__proto__.showX();//跳过了私有属性的查找,直接到公有属性上去找 //p1.showX();//会根据原型链一级级的往上查找; //S.prototype.__proto__.showX() //F.prototype.showX(); //alert(p1.y) p1.__proto__.__proto__.showX=function(){ alert('456789') } p1.showX(); p2.showX();
call继承:
//call继承:把父类私有的属性和方法继承给了子类私有的属性和方法; function F(){ this.x=100; this.y=200; } var f1=new F; console.dir(f1) function S(){ F.call(this) this.z=300; } var p1=new S; console.dir(p1) //私有属性:x:100; y:200
冒充继承:
//冒充继承:把父类私有+公有的属性和方法,克隆(for in循环)了一份一模一样的给子类私有的属性和方法; function F(){//父类; 父类私有的属性和方法 this.x=100; this.y=300; } F.prototype.showX=function(){//父类共有的属性和方法; alert(123); }; function S(){ var tmp=new F; console.dir(tmp) for(var attr in tmp){ this[attr]=tmp[attr]; } }; var p1=new S; console.dir(p1)
混合继承:call继承+原型链继承
/* * call继承:把父类私有的属性和方法,都给了子类私有的属性和方法---call; * 原型链继承:把父类私有+公有的属性和方法,都给了子类公有的属性和方法 * 问题:父类私有的给了子类私有,也给了子类公有 * */ function F(){ this.x=100; } F.prototype.showX=function(){}; function S(){ F.call(this);//完成了call继承 }; S.prototype=new F;//完成了原型链继承; var p1=new S; console.dir(p1); /* * 私有属性:x:100; * __proto__: * x:100; * __proto__: * constructor:F, * showX:function... * */
混合继承:call继承+拷贝继承
//混合继承:call继承+拷贝继承 function extend(newEle,oldEle){ for(var attr in oldEle){ newEle[attr]=oldEle[attr]; } } function F(){ this.x=100; this.showX=function(){} } F.prototype.getX=function(){}; F.prototype.getX1=function(){}; var f1=new F; console.dir(f1) function S(){ F.call(this)//call继承 } extend(S.prototype, F.prototype);//拷贝继承 S.prototype.cc=function(){ } var p1=new S; console.dir(p1);
寄生式组合: call继承+Object.create();
//寄生式组合: call继承+Object.create(); function F(){ this.x=100; } F.prototype.showX=function(){}; function S(){ F.call(this)//只继承了私有的; } function Tmp(){}; Tmp.prototype= F.prototype;//只把父级公有的属性和方法过渡到了一个空类的原型上; S.prototype=new Tmp; S.prototype.constructor=S; var p1=new S; console.dir(p1)
for in拷贝
var obj={name:'zhufeng',age:8}; var obj2={} function extend(newEle,oldEle){ for(var attr in obj){ obj2[attr]=obj[attr]; } }
//for in循环在遍历时,默认会把自己的私有和它所属原型上扩展的属性和方法都遍历到 //obj.propertyIsEnumerable() 、 obj.hasOwnProperty()判断是否私有属性 Object.prototype.aaa=function(){} var obj={ name:'小明', age:8 } console.log(obj)//obj.__proto__ 上有aaa(){} for(var key in obj){ // if(obj.propertyIsEnumerable(key)){ if(obj.hasOwnProperty(key)){ console.log(key) //name age } }
其它:
关于Object.create()
Object.prototype.aaa=function(){} var obj={ name:'小明', age:8 } var obj2=Object.create(obj) //创建一个新对象,把新对象obj作为这个对象的原型 console.log(obj2) //封装Object.create() function object(o){ function Fn(){} Fn.prototype=o return new Fn; } var newObj=object(obj)