借用构造函数的问题《javascript高级程序设计》p168

来源:互联网 发布:2016年网络流行关键词 编辑:程序博客网 时间:2024/05/21 11:28

1、如果仅仅借用构造函数,那么将无法避免构造函数模式存在的问题:方法都在构造函数中定义,因此函数复用就无从谈起.
我的理解是:借用构造函数模式,因为不存在原型链的子类的原型对象指向超类,即如下:子类的实例会共享超类的方法,因为通过构造函数创建的对象各自拥有一份属性,互不共享。
//原型链
//超类构造函数
funtion SuperType() {
this.superproperty = true;
}
//超类的原型对象添加方法getSuperValue()
SuperType.prototype.getSuperValue = function() {
return this.superproperty;
}
//子类的构造函数
function SubType() {
this.subproperty = false;
}
//改写了子类的原型对象,把超类的实例赋给了子类的原型对象。子类的原型对象都拥有了超类的所有属性和方法,相当于继承了。
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
return this.subproperty;
}
借用构函数:解决的问题是,解决原型中包含引用类型值所带来的问题。
基本思想是:在子类的构造函数中调用超类的构函数。(函数只不过是在特定环境中执行代码的对象),该模式下,子类的原型对象没有指向超类的实例。
这种借用构造函数的模式,因为通过构造函数创建的实例对象都会拥有自己的属性的副本了,不会共享同一个引用属性值。
//超类中定义一个引用类型的值-数组
function SuperType() {
this.colors = [“red”,”green”,”blue”];
}
//子类的构造函数中调用了超类的构造函数。
function SubType() {
//call(this,arg1,arg2,…),apply(this,[arg1,arg2,…])
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push(“black”);
instance1.colors;//”red”,”green”,”blue”,”black”
var instance2 = new SubType();
instance2.colors;//”red”,”green”,”blue” //实例instance1 和instance2各自拥有一份colors属性副本,相互不相干。

2、在超类型的原型中定义的方法,对子类而言也是不可见的,结果所有类型都只能使用构造函数模式。构造函数模式下,需要的方法在构造函数中创建,在这里即在子类的构造函数中创建需要的方法。
在超类型原型中定义的方法,如下:
//超类中定义一个属性;
function SuperType() {
this.superproperty = “zhenglijing”;
}
//在超类型的原型对象中添加方法getSuperValue()
SuperType.prototype.getSuperValue() {
return this.superproperty;
}
//子类的构造函数中调用了超类的构造函数。
function SubType() {
//call(this,arg1,arg2,…),apply(this,[arg1,arg2,…])
SuperType.call(this);
}
//调用子类的构造函数创建实例instance,
var instance = new SubType();
var d = instance.getSuperValue();//控制台会报错,Uncaught TypeError: instance.getSuperValue is not a function
//说明超类的原型对象定义的方法对实例而言是不可见的。这样就实现不了方法共享了。不可见的原型是子类的原型对象没有指向超类的实例。
画图说明:
这里写图片描述
超类原型对象定义得到方法对子类的实例不可见,故实现不了方法的共享,所以所有类型不得不适用构造函数模式。
(ECMAScript构造函数用来创建特定类型的对象)
所以需要的方法只能在构造函数中创建,但是使用构造函数创建的实例都会带有一份该方法,造成了性能低下。
补充一下什么是构造函数模式:

function Person(name){
this.name = name;
this.sayName = function() {
alert(this.name);
}
}
//实例instance1和实例instance2都会包含一份方法sayName()
var instance1 = new Person(“zhenglijing”);
var instance2 = new Person(“jingke”);

阅读全文
0 0
原创粉丝点击