前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >40 - 真正理解 Bind、Call 和 Apply​

40 - 真正理解 Bind、Call 和 Apply​

作者头像
前端黑板报
发布2022-12-01 17:19:58
1870
发布2022-12-01 17:19:58
举报
文章被收录于专栏:前端黑板报前端黑板报

原文地址:https://dev.to/bhagatparwinder/truly-understand-bind-call-apply-21da

Bind

JavaScript 中的 this 扮演者重要的角色,在 JavaScript 中它是依据函数是怎么被调用的而不是它在哪声明的(箭头函数则表现为相反)。

我们举一个例子来示范一下 this 是如何工作的:

代码语言:javascript
复制
const sayGreeting = {
    name: "Parwinder",
    hello: function() {
        return `Hello, ${this.name}`;
    }
}

console.log(sayGreeting.hello()); // Hello, Parwinder

hello 方法可以获取 sayGreeting 上的 name 属性,当我用 sayGreeting 调用它时,它是运行在 sayGreeting 对象上下文中的。

相反如果我这样做:

代码语言:javascript
复制
const sayGreeting = {
    name: "Parwinder",
    hello: function() {
        return `Hello, ${this.name}`;
    }
}

const hello = sayGreeting.hello;

console.log(hello === sayGreeting.hello); // true
console.log(hello()); // Hello, undefined

尽管 hello 变量与 sayGreeting 对象上的 hello 方法相等,但它的执行上下文并不是在 sayGreeting 中,而是在 window 或全局状态中。

bind 方法允许我们绑定上下文,它返回一个新的方法且上下文绑定为我们传递给 bind 函数的内容。

代码语言:javascript
复制
const sayGreeting = {
    name: "Parwinder",
    hello: function() {
        return `Hello, ${this.name}`;
    }
}

const hello = sayGreeting.hello.bind(sayGreeting);
console.log(hello()); // Hello, Parwinder

实际业务中哪里需要使用 bind?

上面的所有例子,数据的获取和方法的调用都在一个对象上 bind 的作用并不明显。可有时候当你需要向一个对象借一个方法但运行上下文需要在另一个对象中时,你就需要使用 bind

代码语言:javascript
复制
const sayGreeting = {
    name: "Parwinder",
    hello: function () {
        return `Hello, ${this.name}`;
    }
}

const nameObject = {
    name: "Lauren"
}

const hello = sayGreeting.hello.bind(nameObject);

console.log(hello()); // Hello, Lauren

sayGreeting 对象上有 hello 方法,所以在 nameObject 对象上就没有必要再写一个相同的方法。我可以向 sayGreeting 对象借用它然后运行在 nameObject 上下文中。

Call

callapplybind 是有区别的,bind 返回一个新的方法而 callapply 则立即调用执行方法。callthis 作为第一个参数,其他参数需要一个个的传递。它们都会传递到我们调用的函数中:

代码语言:javascript
复制
const sayGreeting = {
    name: "Parwinder",
    hello: function () {
        return `Hello, ${this.name}`;
    }
}

console.log(sayGreeting.hello.call(sayGreeting)); // Hello, Parwinder

带有其它参数:

代码语言:javascript
复制
const sayGreeting = {
    name: "Parwinder",
    hello: function (trait, color) {
        return `Hello, ${this.name}. I see you ${trait} ${color}. It is my favorite too!`;
    }
}

console.log(sayGreeting.hello.call(sayGreeting, "like", "red"));
// Hello, Parwinder. I see you like red. It is my favorite too!

Apply

尽管 applycall 类似都是直接执行函数,但它接受的是一个数组作为第二个参数而不是逗号分隔的值。

代码语言:javascript
复制
const sayGreeting = {
    name: "Parwinder",
    hello: function () {
        return `Hello, ${this.name}`;
    }
}

console.log(sayGreeting.hello.apply(sayGreeting)); // Hello, Parwinder

当没有其余参数时 applycall 没有区别,但是当我们有其余参数时,使用方法就有点区别:

代码语言:javascript
复制
const sayGreeting = {
    name: "Parwinder",
    hello: function (trait, color) {
        return `Hello, ${this.name}. I see you ${trait} ${color}. It is my favorite too!`;
    }
}

console.log(sayGreeting.hello.apply(sayGreeting, ["like", "red"]));
// Hello, Parwinder. I see you like red. It is my favorite too!

apply 使得传递多个参数变得更容易些,但是现在 ES6 中使用扩展运算符传递多个参数也很容易了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端黑板报 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Bind
    • 实际业务中哪里需要使用 bind?
    • Call
    • Apply
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档