JavaScript this

this用的很多,react 的class component用了这么多自己也比较熟悉的了,下面就来讲讲如何判断一个this的绑定以及call、apply、bind的实现。

判断this绑定

主要就是以下的几点:

  1. 由new调用:绑定到新创建的对象上面。在类里面的contructor中,指向将要通过构造器创建的对象。
  2. 由call、apply、bind来调用,绑定到指定的对象上面。
  3. 由上下文对象调用,就绑定到上下文的对象上面。
  4. 默认:全局对象,node为global,浏览器为window

如何实现call

Function.prototype.call = function(context) {
  var context = Object(context) || window;
  // call是由一个函数调用的,此时this就指向该函数
  context.fn = this;
  var args = [];
  for(let i = 1; i < arguments.length; i++) {
    args.push('arguments[' + i + ']');
  }
  var res = eval('context.fn(' + args + ')');	
  delete context.fn;
  return res;
}

var obj = {
  a: 1
}

function print() {
  console.log(this.a)
}
print.call(obj);

如何实现apply

apply与call的最大区别就是,apply仅有第二个参数apply(obj, arguments),且arguments为一个数组,数组里面存放了要传递给调用call方法的函数的参数

而call则一个一个的接收参数call(obj, argument1, argument2, argument3, ... argumentn)

Function.prototype.apply = function(context, arr) {
  var context = Object(context) || window;
  context.fn = this;
  var res;
  if(!arr) {
    res = context.fn();
  } else {
    var args = [];
    for(let i = 0; i < arr.length; i++) {
      args.push('arr[' + i + ']');
    }
    res = eval('context.fn(' + args + ')');
  }
  delete context.fn;
  return res;
}

var obj = {
  a: 1
}
function bar(b, c) {
  return {
    a: this.a,
    b: b,
    c: c
  }
}
bar.apply(obj, [2,3])

如何实现bind

Function.prototype.bind = function(context) {
  if(typeof this !== "function") {
    throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
  }
  var self = this;
  var args = Array.prototype.call(arguments, 1);
  var fNOP = function() {};
  var fBound = function() {
    self.apply(this instanceof self ? this :context, args.concat(Array.prototype.slice.call(arguments)));
  }
  fNOP.prototype = this.prototype;
  fbound.prototype = new fNOP();
  return bound;
}
原文地址:https://www.cnblogs.com/ssaylo/p/13928993.html