借用构造函数是为了解决引用值类型被所有实例共享的问题。
基本思想是:在子类型构造函数内部通过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
superType.call(this)这句实际上是在(未来将要)新创建的subType实例的环境下调用了superType构造函数。调用这句之后,会在新subType对象上执行superType()函数中定义的所有对象初始化代码(非私有变量或私有函数,即只调用前面加this的属性和函数)。因为此属性并非是原型对象上的属性所以不会被所有实例共享,所以每创建一个实例,都会拥有一个colors属性的副本。
更好的一点是,可以在子类型构造函数中向超类型构造函数传递参数。
看下面这个例子。
function superType(name){ this.name = name; } function subType(age){ //继承了superType,同时还传递了参数 superType.call(this,"Nico"); //实例属性 this.age = age; } var instance = new subType(20); alert(instance.name) //"Nico" alert(instance.age) //20
借用构造函数的问题:
方法都在构造函数中定义,无法做到函数复用。而且,在超类的原型中定义的方法,对子类型而言都是不可见的,结果所有类型都只能使用构造函数模式。