JavaScript中的call继承(也叫借用构造函数继承)
//父类构造函数
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function(){
console.log("Hi!");
}
//子类构造函数
function Student(gender,name,age){
this.gender = gender;
}
Student.prototype.play = function(){
console.log("Hello World!");
}
//通过Student构造函数创建一个实例对象
const s1 = new Student("男");
-
2、做法
//在子类Student构造函数中通过call方法调用Person函数 function Student(gender,name,age){ this.gender = gender; Person.call(this,name,age); }
-
3、解析
-
首先,我们明白构造函数也是一个函数,可以不和new连用,可以直接调用,那么它的this指向window。只是不和new连用的时候,就没有自动创建对象的能力了。
-
然后,Person函数体内的内容就可以添加到window对象上了。
//在调用Person的时候,使用call就可以将Person里面的this指向改为obj //例如: const obj = { message:"我是一个自定义的obj对象" } Person.call(obj,"Jack",20); console.log(obj)//结果在下图
-
再然后,Student构造函数中的this指向的是构造函数的实例对象。在上面的核心做法里面,因为使用call方法调用构造函数Person的时候,已经把Person里的this改为Student里的this了(即实例对象s1),所以name和age属性都添加到了s1身上。
//通过Student构造函数创建一个实例对象 const s1 = new Student("男","Jack",18); console.log(s1);//结果如下图
-
这里要注意过程,上面创建实例对象s1的时候,将“Jack”和18先传给Student里面的name和age,然后在Student里传给了Person里面。然后,Person.call()里面的this又指向了s1,所以name和age就都加到s1上面了。过程类似于以下步骤:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z1vkWIIm-1647495009666)(…/截屏图片/image-20220120173030069.png)]
-
-
-
4、优点:
- 继承来的属性将会直接出现在子类构造函数的实例上。
- 一个实例使用的属性可以在同一个位置上传递参数了。
-
5、缺点:
-
只能继承构造函数体内的内容,构造函数的原型对象上不能继承。就拿上面的来说, s1 实例对象中就没有Person构造函数的原型上的 sayHi 方法。
原因:因为一开始就只是把构造函数当做普通函数来调用,构造函数的原型上的内容是给实例用的,开始就没有new,自然就没有实例。
-