解决原型链中包含引用值类型的问题——借用构造函数

借用构造函数,又叫伪造对象经典继承

这种技术的基本思想是:在子类型构造函数的内部调用超类型的构造函数。别忘了,函数只不过是在特定环境中执行代码的对象,因此通过调用apply()和call()方法也可以在将来新创建的对象上执行构造函数。

例如:

function SuperType(){this.colors = ["red","blue","green"]};

function SubType(){

//继承了superType

SuperType.call(this);

}

var instance1 = new SubType();

instance1.colors.push("black");

alert(instance1.colors);//"red","blue","green","black"

var instance2 = new SubType();

alert(instance2.colors);//"red","blue","green"

解析:虽然color是引用类型值(Array),但是由于在子类型的构造函数里面调用了超类型的构造函数,我们实际上是在将来新创建的SubType实例的环境下调用了SuperType的构造函数,这样就会在新SubType对象上执行SuperType函数中定义的所有对象初始化代码。结果,SubType的每个实例就都会具有自己的color属性的副本了,一个实例修改它的引用类型的时候不会影响另一个实例。

优势:相对于原型链而言,借用构造函数有一个很大的优势,即可以在子类型构造函数中向超类型构造函数传递参数。例如:

function SuperType(){this.name = name;}

function SubType(){

//继承了SuperType,同时还传递了参数

SuperType.call(this.,"Nicholas");

//实例属性

this.age = 29;

}

var instance = new SubType();

alert(instance.name);//"Nicholas"

alert(instance.age);//29

以上代码中的SuperType只接受一个参数name,因此该参数会直接赋值给一个属性。在SubType构造函数内部调用SuperType构造函数时,实际上是为SubType的实例设置了name属性。为了确保SuperType构造函数不会重写子类型的属性,可以在调用超类型构造函数后,再添加应该在子类型中定义的属性。

猜你喜欢

转载自blog.csdn.net/milan_kunderla/article/details/81083001