1. 原型链的继承
把父类私有+公有的属性和方法,都给了子类公有的;(让子类.prototype=父类的实例)
例子:
function F(){
this.x=100; //父类私有
}
F.prototype.showX=function(){}; //父类公有的;
function S(){
this.y=200; //子类私有
}
S.prototype=new F; //核心:把父类私有+公有的属性和方法,都作为子类公有的属性和方法;
S.prototype.constructor=S;//修改S的constructor指向;
var s=new S;
console.dir(s);
2. call继承
把父类私有的属性和方法,给了子类私有的属性和方法;(注意:通过call改变this指向)
例子:
// call()中第一个参数:用来改变this指向
//call()中从第二个参数开始,相当于给call点前面的函数,从左往右一个个的传参;
//注意:call继承只跟父类私有属性和方法有关,跟父类公有的方法没有关系;
function F(){
//this指向F的实例;
this.x=100;//父类私有的
this.showX=function(){
alert(this.x);
}
}
var f=new F;
console.dir(f);
function S(name){//子类构造函数中,都放的是私有的属性和方法;
//this-S的实例
F.call(this);//F中的this-F new出来的实例
this.y=200;
this.name=name;
}
var s=new S('aaa');
console.dir(s);
3. 冒充继承
把父类私有+公有的属性和方法,都给了子类私有的;
例子:
function F(){//父类私有的
this.x=100;
}
F.prototype.showX=function(){};
F.prototype.showY=function(){};
var f=new F;
function S(){
//this-S的实例;
var f=new F;
for(var attr in f){
this[attr]=f[attr];
}
this.aa=123;
}
var s=new S;
console.dir(s);
4. 混合继承1: call继承+原型链继承
call继承:在子类的构造函数中继承,一定要改变this指向;(通过call);
function F(){//私有
this.x=100;
}
F.prototype.showX=function(){};//公有
var f=new F;
console.dir(f);
function S(){//call继承在子类的构造函数中进行继承;
F.call(this);//call继承
}
//原型链继承在子类的prototype上进行继承
S.prototype=new F;//原型链继承;
S.prototype.constructor=S;
S.prototype.aaa='123';
var s=new S;
console.dir(s);
5. 混合继承2: call继承+拷贝继承;
拷贝继承:extend(新对象,old对象);
function extend(obj2,obj1){
for(var attr in obj1){
obj2[attr]=obj1[attr];
}
return obj2;
}
//混合继承2:call继承+拷贝继承
function F(){
this.x=100;
}
F.prototype.showX=function(){};
function S(){
F.call(this);//call继承
}
//拷贝继承:克隆一份一模一样的;
extend(S.prototype, F.prototype);
var s=new S;
console.dir(s);
6. 寄生式组合继承:call继承+Object.create()的思想;
function F(){//父类私有的
this.x=100;
}
F.prototype.showX=function(){} //父类公有的;
//找一个中间类,只把公有的过滤进来;
function Tmp(){}; //没有私有的属性和方法
Tmp.prototype=F.prototype; //Tmp只保留了F类公有的方法;
function S(){
F.call(this);//call继承:把F私有的属性和方法继承过来了;
}
S.prototype = new Tmp;//S.prototype这个原型就相当于tmp的实例;就可以享用Tmp私有+公有的方法;但是我们知道,Tmp没有私有方法;只有公有方法;
S.prototype.constructor=S;
var s=new S;
console.dir(s);
7. 批量操作公有属性,可以用{};
用{}的时候,一定要注意两点:
1. constructor会有问题,我们一定要重写constructor的指向;
2. 系统内置类的公有方法不能批量删除,这是浏览器对系统内置类的自我保护;所以,如果想删除的话,只能一个个的删除;
例子 — 删除公有属性:
Array.prototype.pop={};
Array.prototype.push={};
Array.prototype.shift={};
例子 – 给数组添加一个公有的去重方法
Array.prototype.rmSame=function(){
//this--ary数组
var obj={};//如果对象中没有,给对象添加,如果有了,说明数组中重复了,删除这一项,同时预防数组塌陷;
for(var i=0; i<this.length; i++){
var cur=this[i];
if(obj[cur]===cur){
this.splice(i,1);
i--;
}else{
obj[cur]=cur;
}
}
return this;//去重后的数组;预告:为了链式操作;
};
ary.rmSame();
ary2.rmSame();