原型链继承
原型链基本概念:通俗的说 就是一个子对象的原型对象又指向它自己的原型对象,而这个原型对象又指向它的原型对象,一直到object
原型继承实现:
<script>
function SuperType(){
this.property=true;
}
SuperType.prototype.getSuperValue=function () {
return this.property;
}
function SubType() {
this.subproperty=false;
}
SubType.prototype=new SuperType();
SubType.prototype.getSubValue=function () {
return this.subproperty;
}
var instance=new SubType();
console.log(instance.getSuperValue());
</script>
本质:重写原型对象,把原型对象等于另一个类型的实例,给它换一个新原型.
console.log(instance);
更清晰地了解原型链
这里instance指向SubType的原型,SubType的原型又指向SuperType的原型,SuperType的原型指向Object,getSuperValue()在SuperType.prototype中,而getSubValue()在SubType.prototype中,也就是SuperType中.
注意:在通过原型链实现继承时,不能使用字面量创建原型方法,也就是不能通过字面量往里面添加原型方法,这样会重写原型链.
<script>
function SuperType(){
this.property=true;
}
SuperType.prototype.getSuperValue=function () {
return this.property;
}
function SubType() {
this.subproperty=false;
}
SubType.prototype=new SuperType();
//使用字面量添加新方法会使上一行无效
SubType.prototype={
getSubValue:function () {
return this.subproperty;
},
someOtherMethod:function () {
return false;
}
};
var instance=new SubType();
console.log(instance.getSuperValue());//error
</script>
缺点:
用原型链实现继承,所初始化的实例都会公用一个同一个属性,所以很少使用
<script>
function SuperType(){
this.color=["red","blue","yellow"];
}
function SubType() {
//this.subproperty=false;
}
SubType.prototype=new SuperType();
stance1=new SubType();
instance1.color.push("black");
console.log(instance1.color);//"red","blue","yellow","black"
var instance2=new SubType();
console.log(instance2.color);//"red","blue","yellow","black"
</script>
借用构造函数
实现:
<script>
function SuperType(){
this.color=["red","blue","yellow"];
}
function SubType() {
SuperType.call(this);
}
SubType.prototype=new SuperType();
var instance1=new SubType();
instance1.color.push("black");
console.log(instance1.color);//"red","blue","yellow","black"
var instance2=new SubType();
console.log(instance2.color);//"red","blue","yellow"
</script>
本质:在子类型构造函数的内部调用超类型构造函数,通过call或者apply改变父类的this
通俗的说就是在新的SubType对象上执行SuperType()函数中定义的所有对象初始化代码,所以SubType的每个实例都会具有自己的color属性副本.
可以传递参数
<script src="../JS/jquery 1.12.4.js"></script>
<script>
function SuperType(name) {
this.name=name;
}
function SubType() {
SuperType.call(this,"wsp");
this.age=22;
}
var instance=new SubType();
console.log(instance.name);//wsp
console.log(instance.age);//22
</script>
缺点:方法都在构造函数中调用,无法进行函数复用,所以也很少单独使用.
组合继承
将原型链继承和借用构造函数组合到一块.最常用的继承模式
实现:
<script>
function SuperType(name) {
this.name=name;
this.color=["red","blue","yellow"];
}
SuperType.prototype.sayName=function () {
alert(this.name);
};
function SubType(name,age) {
//继承属性
SuperType.call(this,name);
this.age=age;
}
//继承方法
SubType.prototype=new SuperType();
SubType.prototype.constructor=SubType;
SubType.prototype.sayAge=function () {
alert(this.age);
};
var instance=new SubType("wsp",22);
instance.color.push("black");
console.log(instance.color);//"red","blue","yellow","black"
instance.sayAge();//22
instance.sayName();//wsp
var instance2=new SubType("thh",20);
console.log(instance2.color);//"red","blue","yellow"
instance2.sayAge();//20
instance2.sayName();//thh
</script>
原型式继承
实现:
<script>
function object(o) {
function F() {}
F.prototype=o;
return new F();
}
var Person={
name:"wsp",
friend:["thh","hhp","hhh"]
}
var anotherPerson=Object(Person);
anotherPerson.name="Greg";
anotherPerson.friend.push("Rob");
var yetotherPerson=Object(Person);
yetotherPerson.name="Linda";
yetotherPerson.friend.push("Bob");
console.log(Person.friend);//"thh","hhp","hhh","Rob","Bob"
</script>
本质:object将传人进去的对象执行了一次浅复制,这种继承方式要求必须有一个对象作为另一个对象的基础(也可以说是你要创建的对象),然后传递给object,再根据需要进行修改.
这个例子中,Person就是那个基础对象,传入object中返回一个新对象,这个新对象将Person作为原型,原型里的属性被共享.
后来新增Object.create()方法规范了原型式继承
可传递二个参数,第二个参数可选
<script>
var Person={
name:"wsp",
friend:["thh","hhp","hhh"]
}
//传递一个参数与object方法行为相同
var anotherPerson=Object.create(Person);
anotherPerson.name="Greg";
anotherPerson.friend.push("Rob");
var yetotherPerson=Object.create(Person);
yetotherPerson.name="Linda";
yetotherPerson.friend.push("Bob");
console.log(Person.friend);//"thh","hhp","hhh","Rob","Bob"
</script>
<script>
var Person={
name:"wsp",
friend:["thh","hhp","hhh"]
}
//传递二个参数会增加或覆盖同名属性
var anotherPerson=Object.create(Person,{name:{value:"hhh"}});
console.log(anotherPerson.friend);//"hhh"
</script>
寄生式继承
<script>
function object(o) {
function F() {}
F.prototype=o;
return new F();
}
function createAnother(original){
var clone=object(original);//通过调用函数构造一个新对象
clone.sayHi=function () {
alert("hi"); //以某种方式增强这个对象
};
return clone;
}
var Person={
name:"wsp",
friend:["thh","hhp","hhh"]
}
var anotherPerson=createAnother(person);
anotherPerson.sayHi();//hi
</script>
本质:创建一个仅用于封装继承过程的函数,该函数在内部以某种方式增强对象,在这里的object对象不是必须的,任何能返回新对象的函数都适用于此模式.
睡什么觉,起来打代码 发布了4 篇原创文章 · 获赞 4 · 访问量 2898 私信 关注科比走好,愿天堂也有篮球