绑定函数自动适应于使用 new 操作符去构造一个由目标函数创建的新实例。当一个绑定函数是用来构建一个值的,原来提供的 this 就会被忽略
我们来举个例子,看一下。
var value = 2;
let obj = {
value: 1,
};
function log(name, age) {
this.sport = 'playing';
console.log(this.value, name, age);
}
let print = log.bind(obj, 'hzzzzzzzq');
let obj2 = new print('18');
// undefined hzzzzzzzq 18
console.log(obj2.sport); // playing
从上面结果,我们可以看出,使用 new 进行创建新实例时,this 指向绑定的 obj 已经失效了,返回 undefined。
bind
bind 函数与
call
,apply
的区别是什么呢?bind
函数并不是直接调用的,且返回函数可以参数call、apply
同样,指定的对象(该函数的执行上下文call
相同,都作为参数传入,但是apply
只传入一个数组参数具体对照,可以看我上面的一篇文章,《JavaScript 深入之 call 和 apply 函数》。
我们来看
bind
的特点第一版 - 返回函数
我们来看一下
bind
执行的返回效果吧:由此,我们来写文吗的第一版代码。
我们来看看结果,是不是一样了呢?
这时候,我们得到了一个返回值,并且绑定。
第二版 - 传入参数
我们来看看,不仅在
bind
函数中可以传入参数,其返回的函数也可以传入参数。 我们看下面的例子:我们怎么加入参数呢?
第二版写完了。
第三版 - 作为构造函数使用的绑定函数
接下来就是构造函数啦,最难的部分了。
我们来举个例子,看一下。
从上面结果,我们可以看出,使用
new
进行创建新实例时,this
指向绑定的obj
已经失效了,返回undefined
。但是为什么不会指向全局变量呢?其实就是
new
操作,让现在的this
指向了obj2
。可以来看看
new
操作是怎么实现的,参考我的这篇文章 - 《JavaScript 深入之 new 操作》。肯定有人会对这句代码有疑问
this instanceof resultFn ? this : context
,我们来解释一下。这里我们根据
this
与resultFn
进行instanceof
来判断是构造函数还是普通函数调用。this
指向实例,判断结果为true
,将绑定函数的this
指向该实例,可以让实例获得来自绑定函数的值。this
指向window
,结果为false
,绑定函数的this
指向context
上面的代码真的实现了吗?
好像还不够,存在问题,那就是返回函数的值修改时,也会导致原函数值的修改。
第四版 - 汇总
我们来汇总一下,我们实现
bind
函数的步骤。我们还会对上面的问题进行优化 - 就是通过一个额外的函数进行中转。