OurJS


OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;

欢迎您订阅我们的技术周刊


我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,

欢迎分享您的观点,经验,技巧,心得

让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;


本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(at)ourjs.com

在JavaScript的Array数组中调用一组Function方法


分享到
分类 JS学习   关键字 JavaScript   发布 ourjs  1418274192201
注意 转载须保留原文链接,译文链接,作者译者等信息。  
注* 这是一篇很有趣的文章,可以很好地帮助你了解JavaScript的Function是怎么工作的。

我在看几个月前写的一些代码。在一个数组中(arrays)中存放了一组方法(function),在未来的某个时间要一次性将这些方法都执行一遍。

这是一件非常简单的事,但有关代码的一些始终困扰着我。

假设数组是这样的:

var callbacks = [
  function() { console.log(1); },
  function() { console.log(2); }
];

你只需要遍历这个数组,并调用每个函数即可:

callbacks.forEach(function(callback) {
  callback();
});

使用forEach比较优美的一点是你可以传入一个不需要每次定义的匿名函数。所以我们也可以将这个函数事先定义。

function call(fn) {
  fn();
}
callbacks.forEach(call);

注* 在大量调用时命名函数比匿名函数性能稍好 JavaScript中匿名函数和命名函数的性能差异 

这可以解决问题,但是看上去有点傻。 JS已经有Function.prototype.call为什么我们不能用它的而要自己写。所以我想要直接使用Function.prototype.call来完成这个。

Function.prototype.call


首先要弄清楚的是call的内部实现细节。像大多数JS对象一样,函数也使用原型(prototype),所以这个 prototype 内部, this 指某个特定的实例。所以简化后的调用实现将是这个样子:

Function.prototype.call = function(thisArg, arg1, arg2, ...) {
  CALL_FN_WITH_SCOPE(this, thisArg, arg1, arg2, ...);
}


这将是在不同了JavaScript引擎要实现的功能,但要记住的重要事情是,this 是被调用的函数。
可以在这里查看规范实现细节: http://es5.github.io/#x15.3.4.4


第二件你要知道的是,你可以在原型上调用函数,只要你使用正确。所以让我们先尝试只调用一个函数。

Function.prototype.call(callbacks[0]);


这是行不通的。你只是调用了一个函数,然后调用this。我们也许可以用这种机制写一些奇怪的代码,我们的目的并没有达到。你真正想要做的是用特定的this绑定Function.prototype.call并调用,昏了吗?

Function.prototype.call.call(callbacks[0]);

这个可以工作,但它也只是相当于callbacks[0].call()调用,所以这种方式也非常不好。我们想要解决的是希望将函数作为一个参数传过去执行,而不是创建额外的调用的函数。


Array.prototype.forEach


理解forEach的工作原理也非常重要。可以看看MDN的说明。 

注* forEach语法: arr.forEach(callback[, thisArg])

其中最重要的一点: 第二个参数将被作为该函数执行时的 this 参数。如果你看过规范,你可能看到过[[Call]] - 实际上,你的JS最终会被转化成这样:

myFunction.call(thisArg, item, index, array);

注* forEach回调时传入的参数为 callback(item, index, array)


将他们组合在一起...


我们知道我们想要调用Function.prototype.call,我们知道我们想直接执行这个函数,所以,接下来的尝试:


callbacks.forEach(Function.prototype.call);

但是,这也不工作。它会抛出一个错误。请记住,this 也需要传,我们实际上已经传了一个undefined,因为根本就没有这个参数,以我们数组的例子来看,最终调用就等价于这样:

Function.prototype.call.call(undefined, callbacks[0]);

实际上我们已经接近了,我们想将Function.prototype.call作为this传进去,那样就等价于Function.prototype.call.call的调用。而这又是通过回调实现的。我们差不多在创建一个小的JavaScript俄罗斯套娃(注*大娃套小娃)。有点疯狂,这是它的工作原理。

callbacks.forEach(Function.prototype.call, Function.prototype.call);

我们的目的最终达到了,但实际上这并不是简单的代码, 还相当慢 。所以我不建议你这样写,但它做了一个有趣的实验。

原文地址: 点此
社区评论 ( Beta版 )
OnceDoc 您自己的企业内容管理系统——文档、流程、知识库、报表、网盘All In One

访问404页面,寻找丢失儿童
 热门文章 - 分享最多
  1. NodeJS就是癌症[2011]
  2. NodeJS会是昙花一现吗?
  3. 提高NodeJS网站的安全性:Web服务器防黑客攻击技巧
  4. JavaScript的设计缺陷?浮点运算:0.1 + 0.2 != 0.3
  5. 2015年的JavaScript:Angular之类的框架将被库取代
  6. 什么是IndexedDB:Web离线数据库入门简介及基础教程
  7. HTML5的TCP和UDP Web Socket API草案定稿
  8. 基于HTML5和JavaScript实现的Winamp MP3播放器
  9. Node.JS编码规范指南教程:教你优雅地写JavaScript代码
  10. 避免Node.js中的命令行注入安全漏洞
  11. AirJD-简单好用的免费建站工具

 相关阅读 - JS学习
  1. 2015年的JavaScript:Angular之类的框架将被库取代
  2. 什么是IndexedDB:Web离线数据库入门简介及基础教程
  3. Node.JS编码规范指南教程:教你优雅地写JavaScript代码
  4. JavaScript的设计缺陷?浮点运算:0.1 + 0.2 != 0.3
  5. Debug调试Node.JS:我们是如何定位内存泄漏和无限循环的
  6. 理解JavaScript中的事件路由冒泡过程及委托代理机制
  7. 用JavaScript制作HTML5动画基础
  8. Node.js 包教不包会
  9. 使用Javascript开发OS X应用程序
  10. Node程序中的设计模式

 关键字 - JavaScript
  1. JavaScript中的继承,构造函数以及new关键字的作用
  2. 纽约时报使用Html5 WebRTC记录访问者IP地址
  3. 正则中test、exec、match的简单区别,以及括号的用法
  4. NativeScript的工作原理:用JavaScript调用原生API实现跨平台
  5. 2015年的JavaScript:Angular之类的框架将被库取代
  6. 少年,不要滥用箭头函数啊:JS中lambda表达式的优缺点和使用场景
  7. JavaScript中NaN的秘密
  8. 如何用CSS将select/option文本居中或居右对齐
  9. 什么是Ajax? 详解原生js ajax
  10. 用原生HTML5控件实现输入框自动提示(下拉列表补全)功能

 欢迎订阅 - 技术周刊

我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;


 关注我们

我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊

ourjs官方微信号