apply、call、bind

call、apply 和 bind 是挂在 Function 对象上的三个方法,调用这三个方法的必须是一个函数。


三者差异


在浏览器里,在全局范围内this 指向window对象;

在函数中,this永远指向最后调用他的那个对象;

构造函数中,this指向new出来的那个新的对象;

call、apply、bind中的this被强绑定在指定的那个对象上;

箭头函数中this比较特殊,箭头函数this为父作用域的this,不是调用时的this.要知道前四种方式,都是调用时确定,也就是动态的,而箭头函数的this指向是静态的,声明的时候就确定了下来;

apply、call、bind都是js给函数内置的一些API,调用他们可以为函数指定this的执行,同时也可以传参。

三者大同小异,先来以call为例解析一下过程

var foo = { value: 1}
// 如果不对this进行绑定执行bar() 会返回undefined
function bar () { console.log(this.value)} 
bar.call(foo)  // 1  也就是说call()改变了this的指向,指向了foo

试想当调用call的时候,也就是类似于

var foo = {
 value: 1,
 bar: function(){ console.log(this.value) }
}
foo.bar() //1


也就是说步骤可以是这样

1、将函数设为对象的属性

2、执行这个函数

3、删除这个函数


下面就试着去实现一下(CALL):

Function.prototype.call2 = function (context) {
 context.fn = this //this 也就是调用call的函数,将函数设为对象的属性
 var result = context.fn() // 执行这个函数
 delete context.fn // 删除这个函数
 return result
}
var foo = { value: 1}
function bar () { console.log(this.value)}
bar.call2(foo) // 1

apply

Function.prototype.apply2 = function(context) {
 var context = context || window
 context.fn = this
 var args = arguments[1]
 var result = context.fn(...args)
 delete context.fn
 return result
}

bind

Function.prototype.bind2 = function(context) {
 var self = this
 var [, ...args] = arguments;
 return function () {
     return self.apply2(context, args) // 或者 //return self.apply(context, args)
 }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容