例子
假设有一个构造函数 Cat
function Cat(){}
在它的原型上定义一个方法:
Cat.prototype.food = 'fish';
Cat.prototype.say = function(){
alert('I like ' + this.food)
}
创建一个 Cat
的实例 miao
, 就可以调用原型上的方法
let miao = new Cat();
miao.say(); // I like fish
现在有一个实例 wang
let wang = {
food: 'bone'
}
我们不想重新定义它的 say
方法,就可以通过 call
或者 apply
来调用 miao
的 say
方法
miao.say.call(wang);
miao.say.apply(wang)
也可以直接调用 Cat
的原型链的方法,实际上是相同的,因为 miao
调用的也是原型上的方法
Cat.prototype.say.call(wang)
讲解
call
和 apply
都是为了改变函数运行时的上下文而存在的,也就是了为改变函数体内部 this
的指向。
在举一个例子
let people = {
name: 'jay',
say(age, job){
alert(`名字:${this.name}, 年龄:${age},职业:${job}`)
}
}
let myName = {
name: 'chow'
}
执行 people.say()
people.say(35, 'singer') // 名字:jay, 年龄:35,职业:singer
用 call
改变函数内部 this
的指向
people.say.call(myName, 31, 'coder') //名字:chow, 年龄:31,职业:coder
用 apply
改变函数内部 this
的指向
people.say.apply(myName, [31, 'coder']) //名字:chow, 年龄:31,职业:coder
可以看出 apply
和 this
的区别就是传参形式不同