// ECMAScript 实现继承是依靠原型链来实现的
//原型链
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
}
console.log(SuperType.prototype.constructor);//指针指向SuperType构造函数
function SubType(){
this.subproperty = false;
}
//继承superType SubType构造函数的原型对象 等于 SuperType构造函数的实例
console.log(SubType.prototype.constructor);//指向SubType构造函数
SubType.prototype = new SuperType();//继承 实现的本质是重写原型对象 切断了和之前构造函数的关系
console.log(SubType.prototype.constructor);//也指针指向SuperType构造函数 constructor的指向变了
SubType.prototype.getSubValue = function(){
return this.subproperty
}
var instance = new SubType();
console.log(instance.getSuperValue());//true
//所有引用类型默认都继承了 Object ,而这个继承也是通过原型链实现的
//所有函数的默认原型都是 Object 的实例
//确定原型和实例之间的关系
//第一种方式使用 instanceof 操作符
console.log(instance instanceof SuperType);//true 原型链中出现过的构造函数,结果就会返回 true
console.log(instance instanceof SubType);//true
console.log(instance instanceof Object);//true
//第二种方式使用 isPrototypeOf
console.log(Object.prototype.isPrototypeOf(instance));
console.log(SuperType.prototype.isPrototypeOf(instance));
console.log(SubType.prototype.isPrototypeOf(instance));
//子类型重写超类型中的某个方法,或者需要添加某个方法,一定要放在替换原型的语句之后
function SuperType(){
this.property = true;
}
SuperType.prototype.getSuperTypeValue = function(){
return this.property;
}
function SubType(){
this.subproperty = false;
}
//继承
SubType.prototype = new SuperType();
//添加新方法
SubType.prototype,getSubTypeValue = function(){
return this.subproperty;
}
//重写getSuperTypeValue方法
SubType.prototype.getSuperTypeValue = function(){
return false;
}
var instance = new SubType();
var instance1 = new SuperType();
console.log(instance.getSuperTypeValue());//false
console.log(instance1.getSuperTypeValue());//true 还是调用之前的方法
//在通过原型链实现继承时,不能使用对象字面量创建原型方法。因为这样做就会重写原型链 原型链会被切断
// 原型链的问题
// 因为有些引用类型的值, 不希望被共享, 这也是之前为什么组合模式是最普遍创建对象的原因;但是通过子类型原型对象继承超类型实例的方式,来继承的话, 超类型的实例属性,也就变成了子类型的原型属性了
function SuperType(){
this.colors = ["red", "blue", "green"];
};
function SubType(){};
SubType.prototype = new SuperType();
var instance = new SubType();
var instance2 = new SubType();
// instance.colors.push('black');
console.log(instance.colors);//["red", "blue", "green", "black"]
console.log(instance2.colors);//["red", "blue", "green", "black"] 因为修改的是原型属性, 所以所有的实例都会手影响
//第二个问题:在创建子类型实例的时候,不能向超类型的构造函数中传递参数.
//解决方式 借用构造函数
function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){
SuperType.call(this);//改变SuperType函数this指向SubType函数,this.colors 相当于在SubType函数内, colors相当于变成实例属性
}
var instance1 = new SubType();
// instance1.colors.push('black');
console.log(instance1.colors);//["red", "blue", "green", "black"]
var instance2 = new SubType();
console.log(instance2.colors)// ["red", "blue", "green"]
//传递参数
function SuperType(name){
this.name = name;
}
function SubType(){
SuperType.call(this,'jerry');
this.age = 25;
}
var instance = new SubType();
console.log(instance.name);//jerry
console.log(instance.age);//25
//组合继承 最常用的继承方式
//组合模式创建对象, 在构造函数中写实例属性, 在原型中写原型属性
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('jerry',12);
var instance2 = new SubType();
instance1.sayName();
instance2.sayName();
网友评论