call实现原理

  1. 让函数的this指向obj
  2. 可以在obj内创建一个函数,func赋值给它, obj.func = func;
  3. 用obj调用该函数 obj.func(…);
  4. 删除obj.func ```javascript let obj = { name: ‘Alibaba’ };

function func(x, y) { this.total = x + y; return this; }

// func的this指向obj obj.func = func; console.log(obj.func(100, 200)); delete obj.func;

  1. <a name="Moq5s"></a>
  2. ### call / bind具体实现
  3. <a name="oDF17"></a>
  4. #### bind & call/apply
  5. 1. 都是为了改变函数中的**this指向**
  6. 1. call/apply:**立即**把函数执行
  7. 1. bind: **不是立即**把函数执行
  8. 1. 只是预先把**this**和后期需要传递的**参数 存储起来**
  9. 1. 「**预处理思想** -> 柯理化函数」
  10. ```javascript
  11. // 相当于立即执行函数
  12. ~ function () {
  13. // 非常随机了
  14. const createRandom = () => {
  15. let ran = Math.random() * new Date();
  16. // 随机名字
  17. return ran.toString(16).replace('.', '');
  18. };
  19. /* 内置CALL实现原理 */
  20. function change(context, ...params) {
  21. // this->要执行的函数func context->要改变的函数中的this指向obj
  22. // params->未来要传递给函数func的实参信息{数组} [100,200]
  23. // 校验context类型
  24. // undefined == null undefined !== null
  25. // 这里同时校验 undefined 和 null
  26. context == null ? context = window : null; // context 为null / undefined this就指向window
  27. if (!/^(object|function)$/.test(typeof context)) {
  28. context = Object(context); // 所有类型,转Object类型
  29. }
  30. // 临时设置的属性,不能和原始对象冲突,所以我们属性采用唯一值处理
  31. let self = this,
  32. key = Symbol('KEY'),
  33. result;
  34. context[key] = self; // 添加方法,this指向context
  35. result = context[key](...params); // 执行方法
  36. delete context[key]; // 删除方法
  37. return result;
  38. };
  39. /* 内置BIND的实现原理 */
  40. function bind(context, ...params) {
  41. // this->func context->obj params->[100,200]
  42. let self = this;
  43. // 柯里化
  44. return function proxy(...args) {
  45. // args->事件触发传递的信息,例如:[ev]
  46. params = params.concat(args);
  47. return self.call(context, ...params);
  48. };
  49. };
  50. Function.prototype.bind = bind;
  51. Function.prototype.change = change;
  52. }();
  53. // bind & call/apply
  54. // 都是为了改变函数中的this指向
  55. // + call/apply:立即把函数执行
  56. // + bind:不是立即把函数执行,
  57. // 只是预先把THIS和后期需要传递的参数存储起来「预处理思想 -> 柯理化函数」
  58. function func() {
  59. console.log(this, arguments);
  60. }
  61. var obj = {
  62. name: 'Alibaba'
  63. };
  64. document.body.onclick = func.bind(obj, 100, 200);
  65. // bind的原理,其实就是利用闭包的机制,把要执行的函数外面包裹一层函数
  66. document.body.onclick = function proxy(ev) {
  67. // 最后的目的:把func执行,this改为obj,参数100/200/ev传递给他即可
  68. func.call(obj, 100, 200, ev); //曲线救国
  69. };
  70. let obj = {name:'zhufeng'};
  71. function func(x,y){
  72. this.total=x+y;
  73. return this;
  74. }
  75. let res = func.change(obj,100,200);
  76. //res => {name:'Alibaba',total:300}