# bind.call.apply

Function.prototype.bind2 = function(context) {
  const self = this;
  const args = Array.prototype.slice.call(arguments, 1);

  const fn = function() {};

  const returnFn = function() {
    const bindArgs = Array.prototype.slice.call(arguments, 1);

    console.log("this instanceof fn", this instanceof fn);

    // 当返回函数作文构造函数的时候, this指向的实例, 结果返回true, 将绑定函数的this指向该实例
    // 可以让实例获得来自绑定函数的值
    return self.apply(
      this instanceof returnFn ? this : context,
      args.concat(bindArgs)
    );
  };

  // fn.prototype = this.prototype;
  // returnFn.prototype = new fn();

  // returnFn.prototype = this.prototype;
  fn.prototype = Object.create(this.prototype);

  return returnFn;
};

// const obj = { name: 11 };

// function bb() {
//   console.log(this.name, "log");
// }

// const bb1 = bb.bind2(obj, 123, 456);

// bb1.prototype.value = 1;

// console.log(bb1.prototype.value);
// console.log(bb.prototype.value);

Function.prototype.call2 = function(context) {
  var context = context || window;
  context.fn = this;

  var args = Array.prototype.slice.call(arguments, 1);

  var result = eval("context.fn(" + args + ")");

  delete context.fn;

  return result;
};

Function.prototype.apply2 = function(context, args) {
  var context = context || window;
  context.fn = this;

  var result = eval("context.fn(" + args + ")");

  delete context.fn;

  result;
};

var obj = { name: 11 };

function bb(num) {
  console.log(this.name, "log");
  console.log(num);
}

bb.call2(obj, 777777);
bb.call(obj, 777777);

bb.apply2(obj, [88888]);
bb.apply(obj, [88888]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
Last Updated: 6/27/2023, 7:40:45 PM