在我们的 ES6 之前并没有给我们提供过 extends 继承。我们可以通过构造函数 + 原型对象模拟实现继承,被称为组合继承。
call()
调用这个函数,并修改函数运行时的 this 指向 fun.call(thisArg, arg1, arg2, ...) thisArg: 当前函数 this 的指向对象。 arg1,arg2: 就是普通参数。
//call 方法
function fn(){
console.log('来杯卡布奇诺')
}
//以前调用函数的方式
fn()
//1. call 方法可以调用函数
fn.call()
打印结果:
可以看到 call 也可以调用函数,当然它的主要用途不是作为点用函数,而是用于改变 this 指向。
其实 fn() 这里的指向是 window //call 方法 function fn(){ console.log('来杯卡布奇诺') console.log(this) } //以前调用函数的方式 fn() //其实这里的 fn 指向的是 window window.fn() 打印结果可以看到我们的 fn 方法:
但是如果我们想把 this 的只想改变成别的对象。
//call 方法
function fn(){
console.log('来杯卡布奇诺')
console.log(this)
}
// call() 可以改变这个函数的 this 指向
//定义一个对象
let obj = {
name: 'andy'
}
fn.call(obj)
我们也可以给它传参数,改变 this 指向是不会影响传参的。
//call 方法
function fn(x, y){
console.log(x,y)
console.log('来杯卡布奇诺')
console.log(this)
}
// call() 可以改变这个函数的 this 指向
//定义一个对象
let obj = {
name: 'andy'
}
fn.call(obj, 1, 2)
打印结果:
总结: call 方法有两个作用,可以调用函数,可以改变原来的 this 指向,可以传参。
借用构造函数来继承父类的属性
核心原理:通过 call() 把父类型的 this 指向子类型的 this ,这样就可以实现子类新继承父类型的属性。
例子:
//1. 父构造函数
function Father(uname, age){
this.name = uname
this.age = age
}
//2. 子构造函数
function Son(uname, age){
//首先调用了 Father 构造函数,然后把 Father 构造函数的 this 改成了 Son 构造函数的 this
Father.call(this, uname, age)
}
let son = new Son('张三', '33')
console.log(son.name);
console.log(son.age);
打印结果:
总结:在 ES6 之前如果想要子构造函数继承父构造函数的一些属性,那我们可以把父构造函数调用过来,但是里面有一个细节,我们一定要把父构造函数的 this 利用 call() 这个方法修改成子构造函数的 this 。
利用原型对象继承方法
//我们在 Father 创建一个共有方法
//1. 父构造函数
function Father(uname, age){
this.name = uname
this.age = age
}
Father.prototype.money = function (){
console.log('父亲的财产:100')
}
//2. 子构造函数
function Son(uname, age){
//首先调用了 Father 构造函数,然后把 Father 构造函数的 this 改成了 Son 构造函数的 this
Father.call(this, uname, age)
}
let son = new Son('张三', '33')
console.log(son.name);
console.log(son.age);
son.money()
打印结果:
这里没有继承到是因为 money() 是写在了原型对象里面,我们只是调用了 Father 方法所以找不到。 正确方法:
//1. 父构造函数
function Father(uname, age){
this.name = uname
this.age = age
}
Father.prototype.money = function (){
console.log('父亲的财产:100')
}
//2. 子构造函数
function Son(uname, age){
//首先调用了 Father 构造函数,然后把 Father 构造函数的 this 改成了 Son 构造函数的 this
Father.call(this, uname, age)
}
//将 Son 的原型对象 prototype 实例化一个 Father 对象,这样我们就可以通过 Son 的原型对象,再到 Father 的原型对象找到 money 方法调用
Son.prototype = new Father()
//因为我们 new Father 相当于 Son.prototype = {} 修改了以前的原型对象,所以 Son 的 constructor 已经被改变了,我们需要手动将 constructor 只想正确的 Son 的构造函数
Son.prototype.constructor = Son
//这里我们随意定义一个 Son 的函数是不会被影响的
Son.prototype.exam = function (){
console.log('考试')
}
let son = new Son('张三', '33')
let father = new Father()
console.log(son);
console.log(father);
son.money()
打印结果: