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属性指向这个函数对象,
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属性,除非手动指定一个。