JS 手写bind函数

作者: 抽疯的稻草绳 | 来源:发表于2021-01-07 21:37 被阅读0次

先看一个bind函数的例子:

function fn1(a, b, c) {
    console.log('this', this); // { x: 100 }
    console.log(a, b, c); // 10 20 30
    return 'this is fn1';
}
const fn2 = fn1.bind({ x: 100 }, 10, 20, 30);
const res = fn2();
console.log(res); // this is fn1

如果我们要手写一个bind函数的话,我们需要知道bind拿了什么参数,干了什么:①接收一个对象(this);②接受n个参数;③返回函数。
那么需求我们知道了,如何实现呢?

首先fn1对于Function来说是Function的实例,这个没有问题吧。那么肯定有fn1.__proto__ === Function.prototypeFunction.prototype中是有callapply等函数的API,既然这样我们就用我们原型Function的方法~

我们不确定bind的参数传几个,我们所知道的只是第一个参数是this要指的对象,第二个一直到最后一个参数我们都不确定,所以我们在手写的时候没法一个一个接收参数,所以第一步我们要将第一个参数this对象和后面的参数分离。

下面是步骤:

  1. 先在函数原型上建立一个名为bind1的函数:
Function.proyotype.bind1 = function() {

}

  1. 将参数拆解为数组
    参数我们通过arguments获取,arguments可以获取一个函数的所有参数,不管你传1个还是传100个。但它是一个列表的形态(叫:类数组),不是数组,不好处理,所以我们要把它拆解为数组:
Function.proyotype.bind1 = function() {
    const args = Array.prototype.slice.call(arguments);
}

其中,sliceArray.prototype上的方法,这块可以理解为将arguments这个类数组赋予数组的slice功能。

  1. 获取this(数组的第一项)
Function.proyotype.bind1 = function() {
    const args = Array.prototype.slice.call(arguments);
    const t = args.shift();
}

shift方法将数组的第一项从数组中剔除,改变了原数组,返回了被剔除的这个数组~ 好,这下第一个参数有啦

  1. 找到fn1.bind(...)中的this,赋给self
Function.proyotype.bind1 = function() {
    const args = Array.prototype.slice.call(arguments);
    const t = args.shift();
    const self = this;
}

为了方便,好看,把this赋值给变量self。这块的this就是指:谁调用的这个bind1,就指向谁,比如一开始咱们的例子,如果fn1执行的话,就指向fn1

  1. 处理返回的函数
Function.proyotype.bind1 = function() {
    const args = Array.prototype.slice.call(arguments);
    const t = args.shift();
    const self = this;
    return function() {
        return self.apply(t, args);    
    }
}

结果我们是要输出绑定过的this函数,所以我们这里用apply方法,将之前获取的第一个this对象参数t,和后面的n个参数args传递进去,就是我们想要的结果啦。

检验一下:

function fn1(a, b, c) {
    console.log('this', this); // { x: 100 }
    console.log(a, b, c); // 10 20 30
    return 'this is fn1';
}
Function.proyotype.bind1 = function() {
    const args = Array.prototype.slice.call(arguments);
    const t = args.shift();
    const self = this;
    return function() {
        return self.apply(t, args);    
    }
}
const fn2 = fn1.bind1({ x: 100 }, 10, 20, 30);
const res = fn2();
console.log(res); // this is fn1

bind函数需要再次调用

相关文章

  • js 手写bind函数

    先看一个bind函数的例子: 如果我们要手写一个bind函数的话,我们需要知道bind拿了什么参数,干了什么:①接...

  • JS 手写bind函数

    先看一个bind函数的例子: 如果我们要手写一个bind函数的话,我们需要知道bind拿了什么参数,干了什么:①接...

  • JS_bind

    前言 bind、call、apply 三个改变指向函数,在JS面试中,经常问道。本文收录了 四种 手写bind的方...

  • 面试秘籍之手写系列

    一、手写call函数 二、手写bind函数 三、手写实现new功能的函数 四、手写reduce函数 五、手写防抖函...

  • 手写bind

    手写bind bind语法 bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被指定为...

  • 前端---请你手写一个XXX吧

    目录 手写 call、apply、bind函数 手写去抖和节流两个通用函数

  • JS进阶知识点和常考面试题

    手写 call、apply 及 bind 函数 涉及面试题:call、apply 及 bind 函数内部实现是怎么...

  • JS基础知识4--作用域和自由变量

    题目 一. this的不同应用场景,如何取值? 二. 手写bind函数(bind是改变函数this指向的方法之一)...

  • 手写bind函数

    参考文章:手写bind()函数,理解MDN上的标准Polyfill

  • 手写bind函数

    参考MDN task1:判断Function.prototype.bind是否存在, 如果存在,不重写,不存在,需...

网友评论

    本文标题:JS 手写bind函数

    本文链接:https://www.haomeiwen.com/subject/skutaktx.html