首先看一段代码:

let obj = {
x: 100
}; function fn(y) {
this.x += y;
console.log(this);
}

现在有一个需求:在1秒后,执行函数fn,并让其this指向obj。

如果写成

setTimeout(fn, 1000);

这么写的话,fn函数中的this是指向window的,而且也没有传递参数。

如果写成

setTimeout(fn(200), 1000);

这么写的话,this指向依然是window,而且相当于立即执行fn函数,并把结果赋给定时器1秒后再执行,这样肯定不行。

如果写成

setTimeout(fn.call(obj,200), 1000);

这么写的话,用call或apply虽然改变了this指向,但都是函数立即执行并把返回结果赋给了定时器,依然无法完成需求。

如果写成

setTimeout(function() {
fn.call(obj, 200);
}, 1000);

这么写的话,用一个匿名函数包起来,等到1秒后执行匿名函数里边的代码,这样便可以完成上述需求。

从中我们可以看出,在某一个阶段之后执行某些代码,我们需要预先把this指向、参数等预先准备好,这种预先处理的思想即柯理化思想。

即,柯理化函数的思想:利用闭包的机制,把一些内容事先存储和处理了,等到后期需要的时候拿来用即可。
 

当然,这个需求如果用bind写的话,也能实现
setTimeout(fn.bind(obj,200), 1000);
因为bind不会立即执行函数,而且可以预先存储一些内容,和柯理化函数的思想相似,但问题是bind不兼容IE8及以下,那么为了通用,我们可以自己封装一个bind方法,从而实现这种需求。
 
/*
* bind:预先处理内容
* @params
* func:要执行的函数
* context:需要改变的this指向
* args:给函数传递的参数
* @return
* 返回一个代理函数
*/
function bind(func, context, ...args) {
return function proxy() {
func.call(context, ...args); //call和apply兼容低版本IE
};
}

完成最开始的需求

setTimeout(bind(fn, obj, 200), 1000);

理解了这种思想,有助于我们更好的阅读别人的代码,如redux源码中applyMiddleware.js、combineReducers.js等很多都用到了这种方式或思想,以后更有助于我们自己写一些插件、组件等。

 
 

最新文章

  1. [js] 变量空值研究
  2. 微信支付报错:Invalid thumbnail dimensions: 0x0
  3. Javascript模式(第二章基本技巧)------读书笔记
  4. HDFS
  5. ubuntu dhcp修改ip地址
  6. sd 卡驱动--基于高通平台
  7. 公用的stringUtil工具
  8. NoSQL 数据库系统对比
  9. FastMM内存泄露
  10. pygame系列_游戏窗口显示策略
  11. 直接选择排序----java实现
  12. 四大高质量且实用的chrome翻译插件推荐
  13. LVDS/RGB转EDP稳定方案----NCS8801S
  14. obj-c编程15[Cocoa实例01]:一个会发声的随机数生成器
  15. FastReport导出PDF乱码的问题
  16. Spring中的CharacterEncodingFilter
  17. MyEclipse部署WebLogic
  18. crm作业知识点集合[二]
  19. 一个struts2程序
  20. c++对象的生命周期

热门文章

  1. GCC编译Win图形程序不显示控制台方法
  2. python读取文件使用相对路径的方法
  3. .NET Core微服务二:Ocelot API网关
  4. Linux中软件安装包的格式
  5. LXC(LinuX Container)之namespaec和cgroup
  6. 通过openjdk源码分析ObjectMonitor底层实现
  7. SpringBoot学习遇到的问题(1) - 配置文件有日志的debug模式等配置项,为什么不起作用
  8. LoadIcon的使用
  9. 如何播放 WAV 文件?
  10. 计算机网络 & 网络编程 期末总结与测评题