再嚼一嚼call,apply,bind

760 阅读3分钟

Call、apply、bind、的区别

这三个都是为了改变this指向而存在的,使用上会有一些不同,先来看一张图

call的使用

1var a = {
2    des:'可爱的你'
3}
4function fn(age,name{
5        console.log(age,name,this.des)
6}
7//执行
8fn.call(a,18,'支付宝');
执行结果
一起来仿写一个call
 1Function.prototype.myCall = function(context{
2    //拿到第一个参数,用户传的对象
3  var context = context || window;
4  //拿到除了第一个对象的,其他剩余参数
5  var args = [...arguments].slice(1);
6  //把当前函数挂载在传过来的对象上
7  context.fn = this;
8  //执行挂载的函数
9  var result = context.fn(...args);
10  //删除挂载对象
11  delete context.fn;
12  //返回执行结果
13  return result;
14}
执行结果

看完call,再看下apply,原理是一样的

使用方式
1var a = {
2  des'帅气的你'
3}
4function fn (age, name{
5    console.log(age, name, this.des)
6}
7//执行,apply第二个参数是一个数组
8fn.apply(a, [18,'微信'])
执行结果
同样我们一起来仿一个apply的实现
 1Function.prototype.myApply = function(context{
2      //获取第一个参数对象
3        var context = context || window;
4      //获取除来第一个参数,其他剩余参数
5      var args = arguments.slice(1)[0];
6      //挂载当前函数到传过来的对象上
7      context.fn = this;
8      //执行函数
9      var result = context.fn(...args);
10      //删除挂载对象
11      delete context.fn;
12      //返回结果
13      return result;
14}
执行结果

bind的使用

1let a = {
2    des'完美的你'
3}
4function fn (age, name{
5        console.log(age,name,this.des)
6}
7//执行,⚠️bind返回是一个函数,所以需要再加()执行
8fn.bind(a,18,'余额宝')();
执行结果
同样我们仿写一个bind实现
 1Function.prototype.Mybind = function (context{
2        //首先需要判断调用方式是否正确
3      if(typeof this !== 'function') {
4          throw new TypeError('Error');
5    }
6      //存储下当前函数
7      var _this = this;
8      //获取参数
9      var args = [...arguments].slice(1);
10      //返回一个函数
11      return function F ({
12      //需要考虑是否被new的情况
13      if(this instanceof F) {
14            return new _this(...args,...arguments)
15      }
16      //否则通过apply返回结果
17      return _this.apply(context,args.concat(...arguments));
18        }
19}
执行结果

~~每天分享一点点,和你共同进步~~