call和bind本质上是apply方法的语法糖
一、关联
今天看到一篇手写bind的文章,首先提到绑定隐式丢失的问题,然后提出普遍的解决方法是call和apply
function foo() {
console.log( this.a);
}
var obj = {
a: 2
};
var bar = function() {
foo.call(obj);
};
bar(); // 2
setTimeout(bar, 100); // 2
接着提到,由于这种用法很常用,所以ES5提出了Function.prototype.bind()方法。
从原博的bind实现可以看出bind实现中最重要的是
return _self.apply(_this, args.concat(Array.prototype.slice.call(arguments)))
因此bind的本质是返回一个函数,函数执行apply
二、区别
功能上三者都是改变this的指向。三者主要的区别在于方法的实现形式和参数传递:
①:func.call(obj,arg1,arg2....)
②:func.apply(obj,[arg1,arg2,...])
③:var ss=this.bind(obj,arg1,arg2,....)
前两者是立即执行的,bind则返回一个函数,以便在需要时调用
下面是原博的bind()实现
Function.prototype.myBind = function(thisArg) {
if (typeof this !== 'function') {
return
}
var _self = this
var args = Array.prototype.slice.call(arguments, 1)
var fnNop = function () {} // 定义一个空函数
var fnBound = function () {
var _this = this instanceof _self ? this : thisArg
return _self.apply(_this, args.concat(Array.prototype.slice.call(arguments)))
}
// 维护原型关系
if (this.prototype) {
fnNop.prototype = this.prototype;
}
fnBound.prototype = new fnNop();
return fnBound;
}