解析 Call/Apply 原理,并手写 Call/Apply 实现

开发 前端
apply() 方法调用一个具有给定 this 值的函数,以及作为一个数组(或[类似数组对象)提供的参数。

[[437510]]

本文转载自微信公众号「三分钟学前端」,作者sisterAn  。转载本文请联系三分钟学前端公众号。

Function.prototype.call()

call() 方法调用一个函数, 其具有一个指定的 this 值和多个参数(参数的列表)。

  1. func.call(thisArg, arg1, arg2, ...) 

它运行 func,提供的第一个参数 thisArg 作为 this,后面的作为参数。

看一个简单的例子:

  1. function sayWord() { 
  2.   var talk = [this.name'say', this.word].join(' '); 
  3.   console.log(talk); 
  4.  
  5. var bottle = { 
  6.   name'bottle',  
  7.   word: 'hello' 
  8. }; 
  9.  
  10. // 使用 call 将 bottle 传递为 sayWord 的 this 
  11. sayWord.call(bottle);  
  12. // bottle say hello 

所以,call 主要实现了以下两个功能:

  • call 改变了 this 的指向
  • bottle 执行了 sayWord 函数

模拟实现 call

模拟实现 call 有三步:

  • 将函数设置为对象的属性
  • 执行函数
  • 删除对象的这个属性
  1. Function.prototype.call = function (context) { 
  2.   // 将函数设为对象的属性 
  3.   // 注意:非严格模式下,  
  4.   //   指定为 null 和 undefined 的 this 值会自动指向全局对象(浏览器中就是 window 对象) 
  5.   //   值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象(用 Object() 转换) 
  6.   context = context ? Object(context) : window;  
  7.   context.fn = this; 
  8.      
  9.   // 执行该函数 
  10.   let args = [...arguments].slice(1); 
  11.   let result = context.fn(...args); 
  12.      
  13.   // 删除该函数 
  14.   delete context.fn 
  15.   // 注意:函数是可以有返回值的 
  16.   return result; 

Function.prototype.apply()

apply() 方法调用一个具有给定 this 值的函数,以及作为一个数组(或[类似数组对象)提供的参数。

  1. func.apply(thisArg, [argsArray]) 

它运行 func 设置 this = context 并使用类数组对象 args 作为参数列表。

例如,这两个调用几乎相同:

  1. func(1, 2, 3); 
  2. func.apply(context, [1, 2, 3]) 

两个都运行 func 给定的参数是 1,2,3。但是 apply 也设置了 this = context。

call 和 apply 之间唯一的语法区别是 call 接受一个参数列表,而 apply 则接受带有一个类数组对象。

需要注意:Chrome 14 以及 Internet Explorer 9 仍然不接受类数组对象。如果传入类数组对象,它们会抛出异常。

模拟实现 apply

  1. Function.prototype.apply = function (context, arr) { 
  2.     context = context ? Object(context) : window;  
  3.     context.fn = this; 
  4.    
  5.     let result; 
  6.     if (!arr) { 
  7.         result = context.fn(); 
  8.     } else { 
  9.         result = context.fn(...arr); 
  10.     } 
  11.        
  12.     delete context.fn 
  13.     return result; 

 

责任编辑:武晓燕 来源: 三分钟学前端
相关推荐

2024-03-15 08:21:17

bindJavaScrip函数

2021-12-05 08:27:56

Javascript 高阶函数前端

2011-03-22 09:49:15

JavaScript

2021-06-18 07:16:17

JavaScript apply()方法call()方法

2017-10-10 14:36:07

前端Javascriptapply、call、

2021-06-09 07:01:30

前端CallApply

2015-03-02 09:22:09

Javascript函数用法apply

2021-12-01 06:40:32

Bind原理实现

2011-08-15 12:55:54

SQL ServerOUTER APPLYCROSS APPLY

2022-02-17 20:57:07

OpenHarmon操作系统鸿蒙

2009-06-24 11:12:17

callerJavascript

2020-12-18 05:42:46

reduxactions

2022-07-27 08:27:34

Call前端

2015-12-24 09:48:40

JavaScriptthis指针深

2021-04-18 07:58:22

SQL Server数据库Apply

2022-06-16 11:06:07

开源Grafanaon-call

2022-05-26 08:12:39

PandasApply技巧

2020-07-31 07:55:21

JavaFuture接口

2017-07-14 08:14:54

Python函数

2011-08-01 16:53:39

MySQLMySQL Apply
点赞
收藏

51CTO技术栈公众号