为什么说 bind 的实现非常考验对原型链的理解?

前言

bind 的实现其实非常考验对原型链的理解。

bind 和 apply,call 是 JS 修改 this 指向的三把利器 🔱。

对于 apply,call 来说,bind 的区别在于会返回一个修改了 this 指向的新函数,并不会立即执行。

但看似简单的内容,实则包含了 JS 的两大核心内容:原型链和构造函数 (new) 。

这篇文章分为两部分:

  • 一部分讲如何实现一个基础版本的 bind 方法,带大家做好热身运动;
  • 另一部分进入主题,详细讲解如何通过原型链来实现一个让人眼前一亮的 bind 方法 ✨。

一、实现 bind 方法

简单说,bind 方法会返回一个改变了 this 指向的新方法。

举个 🌰:

var name = 'Jack';
var Yve = {
   
    name: 'Yvette'
};
function person() {
   
    console.log(this.name);
}
person(); // Jack
var bindYve = person.bind(Yve);
bindYve(); // Yvette

根据这个特点,我们来实现第一版的 bind 方法:


// v1.0:返回一个改变了 this 指向的方法

Function.prototype.bind2 = function (context) {
   
    // 首先要获取调用bind的函数,也就是绑定函数,用this可以获取
    var self = this; // 用self绑定this,因为下面函数中的this指向已经改变(存放当前函数的this)
    return function () {
   
        // 用apply来改变this指向(apply的实现并不复杂,文末放有链接可以查看)
        self.apply(context);
    }
}

bind 方法的另一个特点是:函数的参数可以分多次传入,即可以在 bind 中传入一部分参数,在执行返回的函数的时候,再传入另一部分参数。

举个 🌰:

var name = 'Jack';
var Yve = {
   
    name: 'Yvette'
};
function person(age, job, gender) {
   
    console.log(this.name, age, job, gender);
}
person(22, 'engineer', 'female');
// Jack 22 engineer female
var bindYve = person.bind(Yve, 22, 'engineer');
bindYve('female');
// Yvette 22 engineer female

根据这个特点,我们来实现第二版的 bind 方法:


// v2.0:分段接收参数

Function.prototype.bind2 = function (context) {
   
    // 首先要获取调用bind的函数,也就是绑定函数,用this可以获取
    var self = this; // 用self绑定this,因为下面函数中的this指向已经改变(存放当前函数的this)
    var args = [...arguments].slice(1); // 用slice方法取第二个到最后一个参数(获取除了this指向对象以外的参数)
    return 
实现一个 `bind` 方法,可以考虑使用原型链的方式来实现。 首先,我们需要定义 `bind` 方法,它接受一个 `this` 参数和任意数量的参数,并返回一个的函数。这个的函数会在调用时将 `this` 绑定到指定的对象,并传递给定的参数。 下面是一个使用原型链实现 `bind` 方法的示例代码: ```javascript Function.prototype.bind = function (context, ...args) { const fn = this; // 原函数 return function (...innerArgs) { return fn.apply(context, args.concat(innerArgs)); }; }; ``` 上述代码中,我们将 `bind` 方法定义在 `Function.prototype` 上,这样所有的函数对象都可以直接调用 `bind` 方法。 在 `bind` 方法内部,我们将原函数保存在 `fn` 变量中。然后返回一个的函数,在这个函数中,我们使用 `apply` 方法将原函数以指定的 `context` 为上下文来调用,并将传入的参数与函数调用时的参数合并起来。 使用示例: ```javascript const obj = { name: 'Alice', }; function sayHello() { console.log(`Hello, ${this.name}!`); } const boundFn = sayHello.bind(obj); boundFn(); // 输出:Hello, Alice! ``` 在上述示例中,我们定义了一个对象 `obj` 和一个函数 `sayHello`。然后通过 `bind` 方法将 `sayHello` 函数绑定到 `obj` 对象上,并返回一个的函数 `boundFn`。当调用 `boundFn` 时,它会在 `obj` 对象上下文中执行 `sayHello` 函数,并输出 `Hello, Alice!`。 希望这个示例可以帮助你理解如何使用原型链实现 `bind` 方法
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值