一、call call是一个方法,是函数的方法
function fun() {
console.log('hello, guoyu')
}
// call 可以调用函数
fun.call() // 输出hello, guoyu
function fun() {
console.log(this.name)
}let cat = {
name: '喵喵'
}
// 上面两段代码,一点关系没有
// 但我们可以通过一个call就可以建立起他们的关系
// call可以调用函数,call可以改变函数中的this
// 让函数中的this指向这个cat对象,本身函数中的this是指向window/global的
fun.call(cat) // 喵喵
【2022面试|前端基础(call、apply、bind的基本概念)】看下面例子
let dog = {
name: '旺财',
sayName: function() {
console.log(`我是${this.name}`)
}
}let cat = {
name: '喵喵'
}
dog.sayName() // 我是旺财
function fun() {
console.log(this.name)
}let dog = {
name: '旺财',
sayName: function() {
console.log(`我是${this.name}`)
}
}let cat = {
name: '喵喵'
}
// dog.sayName() // 我是旺财
// 如果我想实现喵喵怎么办,可是cat没有sayName这个方法啊
// 可以使用call借用,让猫去用狗的方法
dog.sayName.call(cat) // 我是喵喵
上面都是简单的,如果再难点呢,比如,狗子里再加个eat方法,带有其他参数。
let dog = {
name: '旺财',
sayName: function() {
console.log(`我是${this.name}`)
},
eat: function(food1, food2) {
console.log(`${this.name}喜欢吃${food1}、${food2}`)
}
}let cat = {
name: '喵喵'
}dog.eat('骨头', '屎') //我喜欢吃骨头、屎
// 如果猫想用这个方法呢, call的用法
dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠
二、apply apply和call的用法几乎是一样的,call第二个参数开始是参数列表,apply只是把这些参数整到一个数组中
let dog = {
name: '旺财',
sayName: function() {
console.log(`我是${this.name}`)
},
eat: function(food1, food2) {
console.log(`${this.name}喜欢吃${food1}、${food2}`)
}
}let cat = {
name: '喵喵'
}dog.eat('骨头', '屎') //我喜欢吃骨头、屎
// 如果猫想用这个方法呢, call的用法
dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠
// 如果是apply,参数改成[数组]方式即可
dog.eat.apply(cat, ['鱼', '老鼠'])
文章图片
三、bind bind和call有点不同,call会调用比如前面的eat函数,bind不会,bind返回的是一个函数,还需要再手动调用一次 。
let dog = {
name: '旺财',
sayName: function() {
console.log(`我是${this.name}`)
},
eat: function(food1, food2) {
console.log(`${this.name}喜欢吃${food1}、${food2}`)
}
}let cat = {
name: '喵喵'
}dog.eat('骨头', '屎') //我喜欢吃骨头、屎
// 如果猫想用这个方法呢, call的用法
dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠
// 如果是apply,参数改成[数组]方式即可
dog.eat.apply(cat, ['鱼', '老鼠'])const fun = dog.eat.bind(cat, '鱼', '老鼠')
fun()
文章图片
四、call、apply、bind的实际应用 实现继承
// 继承:子类可以使用父类的方法
function Animal() {
this.eat = function() {
console.log('吃东西')
}
}let ani = new Animal()
ani.eat() // 吃东西// 下面的代码和上面毫无关系,并没有形成继承关系
function Cat () { }
let cat = new Cat()
cat.eat() // 肯定会报错
文章图片
看看使用call方式实现继承
// 继承:子类可以使用父类的方法
function Animal() {
// 自然而然这里的this也是指向小cat了----2
// 那么this.eat 就是小cat.eat,那么小cat就有这个eat方法了
this.eat = function() {
console.log('吃东西')
}
}let ani = new Animal()
ani.eat() // 吃东西// 如何才能让Cat继承Animal呢
function Cat () {
// Animal 是构造函数,它也是函数,就可以直接调call,就把this传进去
// 已经实现了继承
// 这里的this指向小cat----1
Animal.call(this)
}
let cat = new Cat()
cat.eat()
文章图片
而且call还可以实现多重继承
// 继承:子类可以使用父类的方法
function Animal() {
// 自然而然这里的this也是指向小cat了----2
// 那么this.eat 就是小cat.eat,那么小cat就有这个eat方法了
this.eat = function() {
console.log('吃东西')
}
}function Bird() {
this.fly = function() {
console.log('I can fly')
}
}let ani = new Animal()// 如何才能让Cat继承Animal呢
function Cat () {
// Animal 是构造函数,它也是函数,就可以直接调call,就把this传进去
// 已经实现了继承
// 这里的this指向小cat----1
Animal.call(this)
Bird.call(this)
}
let cat = new Cat()
cat.eat()
cat.fly()
推荐阅读
- 2022面试|前端基础(BFC)
- 前端|如何将项目上传到Gitee上
- 数据资产为王,如何解析企业数字化转型与数据资产管理的关系()
- Django全栈开发|【Python+Django】一个博客网站的设计和代码实现
- Docker学习记录|关于Docker你不知道的那些事之Docker容器数据卷
- 青龙面板-来自保姆的喂饭|(九)青龙Tools 正式版/前端网页提交+后台管理/适用于所有场景/开饭开饭开饭 【2022年6月15日】【更新】
- nodejs-express项目初始化
- 人工智能|讯飞大数据竞赛2022 汽车领域多语种迁移学习 打卡博客
- Android基础入门|【毕业季_进击的技术er】送别过去两年迷茫的自己。重整旗鼓,大三我来啦