组合继承第6.3.3讲为什么修复构造函数指向

function SuperType(name){  
this.name = name;  
this.colors = ["red", "blue", "green"];  
}  
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 instance1 = new SubType("Nicholas", 29);  
instance1.colors.push("black");  
alert(instance1.colors); //"red,blue,green,black"  
instance1.sayName(); //"Nicholas";  
instance1.sayAge(); //29  
var instance2 = new SubType("Greg", 27);  
alert(instance2.colors); //"red,blue,green"  
instance2.sayName(); //"Greg";  
  
instance2.sayAge(); //27  
剖析:
1)原型是属于一个函数对象的
2)原型是一个对象
3)以一个原型具有constructor属性,指向一个函数对象
4)在默认情况下,一个函数对象的原型的contructor属性指向这个函数对象, 

默认的:

function SuperType(name){
    this.name =name;
    this.colors = ["red","blue","green"];
    this.sex = "man"
}
SuperType.prototype.sayName = function(){
    console.log(this.name);
};

SuperType.prototype.constructor指向默认的SuperType函数对象;

非默认的:
prototype是指向一个对象的,那么也就意味着我可以直接赋一个对象给prototype属性

SubType.prototype = new SuperType();

就是如此-SubType通过原型链就“继承”了SuperType的prototype中定义的方法及SuperType实例方法及属性

此时的SubType.prototype.constructor就指向SuperType的实例对象的constructor,这个值就是SuperType函数

console.log(SubType.prototype.constructor===SuperType);//true
如果继承代码到此为止的话,带来的一个问题就是SubType不能正确地反应其真实地constructor

var instanceSub=new SubType();
console.log(instanceSub instanceof SubType);//true
console.log(instanceSub instanceof SuperType);//true

instanceSub是SubType构造函数的实例,但是SubType原型的构造函数却是SuperType,这个就和原型"继承"的设计语义相违背了。

这个问题可以通过重新设置constructor来解决

SubType.prototype.constructor = SubType;

SubType原型的构造器对象指向了SubType

各归其位,各司其职

SubType的原型继承了SuperType,是为了继承SuperType的原型方法,但实例化的时候,连带constructor属性一起改变了。constructor本身是要指向prototype属性所在的函数,为了能够确定对象原本的指向,也就是SubType,要将这个属性指回原本的构造函数,SuperType的方法依然会被继承。
constructor本来就是构造函数的意思,子类当然要有自己的构造函数啊,正是因为SubType.prototype = new SuperType()有副作用,使SubType.prototype.constructor指向了SuperType,所有才需要SubType.prototype.constructor = SubType来纠正这个副作用。

SubType.prototype = new SuperType();

让SubType继承SuperType的属性跟方法。但是这样SubType.prototype.constructor会被SuperType.prototype.constructor,也就是SuperType给替换掉,就会将原先SubType的构造函数属性给删除掉。

SubType.prototype.constructor = SubType;

这句是重新将构造函数属性给恢复回来,从而实现仅仅是继承了SuperType的属性方法而不改变其他属性。

《Javascript启示录》 中的  8.8 用新对象替换prototype属性会删除默认构造函数属性。
可以用一个新值来替换prototype属性的默认值,然而,这么做会将删除在“预制”原型对象中找到的默认constructor属性,除非手动指定一个。





评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值