JS|JS 手写bind函数
先看一个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.prototype
。Function.prototype
中是有call
、apply
等函数的API,既然这样我们就用我们原型Function
的方法~我们不确定bind的参数传几个,我们所知道的只是第一个参数是
this
要指的对象,第二个一直到最后一个参数我们都不确定,所以我们在手写的时候没法一个一个接收参数,所以第一步我们要将第一个参数this
对象和后面的参数分离。下面是步骤:
- 先在函数原型上建立一个名为
bind1
的函数:
Function.proyotype.bind1 = function() {}
- 将参数拆解为数组
参数我们通过arguments
获取,arguments
可以获取一个函数的所有参数,不管你传1个还是传100个。但它是一个列表的形态(叫:类数组),不是数组,不好处理,所以我们要把它拆解为数组:
Function.proyotype.bind1 = function() {
const args = Array.prototype.slice.call(arguments);
}
其中,
slice
是Array.prototype
上的方法,这块可以理解为将arguments
这个类数组赋予数组的slice
功能。- 获取this(数组的第一项)
Function.proyotype.bind1 = function() {
const args = Array.prototype.slice.call(arguments);
const t = args.shift();
}
用
shift
方法将数组的第一项从数组中剔除,改变了原数组,返回了被剔除的这个数组~ 好,这下第一个参数有啦- 找到
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
。- 处理返回的函数
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
传递进去,就是我们想要的结果啦。【JS|JS 手写bind函数】检验一下:
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函数需要再次调用
推荐阅读
- 一起来学习C语言的字符串转换函数
- C语言字符函数中的isalnum()和iscntrl()你都知道吗
- C语言浮点函数中的modf和fmod详解
- C语言中的时间函数clock()和time()你都了解吗
- 概率论/统计学|随机变量 的 分布函数 与 概率密度函数 的区别
- vue组件中为何data必须是一个函数()
- iOS-Swift-map|iOS-Swift-map filter reduce、函数式编程
- R语言|R语言 函数
- 2018-05-30闭包和函数
- 函数的一些东西