Javascript 函数(){return fn.apply(me,arguments);}作为回调
最近Monole.io的开源代码中有一些我不理解的coffee脚本/mvc代码。如果我查看Chrome控制台中的源代码(它显示JavaScript,而不是coffeescript),在每个连接文件的顶部,就在类声明之前,有这样一个函数。例如,创建集合的代码的第一部分如下Javascript 函数(){return fn.apply(me,arguments);}作为回调,javascript,coffeescript,Javascript,Coffeescript,最近Monole.io的开源代码中有一些我不理解的coffee脚本/mvc代码。如果我查看Chrome控制台中的源代码(它显示JavaScript,而不是coffeescript),在每个连接文件的顶部,就在类声明之前,有这样一个函数。例如,创建集合的代码的第一部分如下 __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; $ = jQuery; Events =
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
$ = jQuery;
Events = require('events');
Collection = (function() {
但是,在coffeeScript中,此函数
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
没有出现。它仅在代码编译为JavaScript时显示
问题1。为什么该函数只出现在已编译的JavaScript中
接下来,它似乎是相同的功能
function (){ return fn.apply(me, arguments); }
在整个代码中作为回调传递给许多不同的函数。例如,在集合类中,它是传递给each函数的回调
each: (callback) =>
@all().promise.done (records) =>
callback(rec) for rec in records
它也是传递给Model类(在应用程序的MVC部分)中的这个观察者函数的回调
我大致了解这个函数是如何工作的
function (){ return fn.apply(me, arguments); }
这仅仅意味着函数
fn
是在me
的上下文中调用的,传递给它的任何参数都由参数表示,但是,我不理解它在这个应用程序中是如何工作的。为什么它不是在原始coffeescript中生成的,而是在编译的JavaScript中生成的,问题2)MVC应用程序中是否有一些东西使它适合作为所有这些不同函数的回调,或者为什么它作为回调传递给所有这些函数?让我们看一个简化的coffeescript示例:
class C
m: => console.log(@)
这就是JavaScript:
var C,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
C = (function() {
function C() {
this.m = __bind(this.m, this);
}
C.prototype.m = function() {
return console.log(this);
};
return C;
})();
这是您的\u绑定
。如果我们看看它是如何使用的,那么事情可能会更清楚:
this.m = __bind(this.m, this);
它出现在C
构造函数中,它用\u bind
返回的函数替换m
方法,因此我们有效地实现了:
var m = this.m;
var _this = this;
this.m = function() {
return m.apply(_this, arguments);
};
我们看到m
方法结束时总是将this
作为C
实例,而不管如何调用它:
c = new C
c.m() # @ (AKA 'this') is `c` inside `m`.
f = c.m
f() # @ is again `c` inside `f`
(请打开控制台)
将其与m:->console.log(@)
的行为进行比较:
您可以在这两个演示链接中看到完整生成的JavaScript
那么这个->
和=>
的东西到底是怎么回事?在CoffeeScript中,使用->
或=>
定义函数或方法。区别在于:
函数绑定
在JavaScript中,this
关键字的作用域是动态的,表示
当前函数附加到的对象。如果你通过考试
函数作为回调函数或将其附加到另一个对象
此
的原始值将丢失。[……]
胖箭头=>
既可用于定义函数,也可用于绑定
将其设置为当前值此
,即在现场。这很有帮助
使用基于回调的库(如Prototype或jQuery)时
创建要传递给每个
或事件处理程序的迭代器函数
与bind
一起使用的函数。使用fat箭头创建的函数如下所示:
能够访问定义此的属性
请注意文档中该部分对回调的讨论。你看到了每个的所有绑定内容,因为有人希望能够说:
something_that_calls_back(obj.each)
调用时,将this
beobj
放入each
。谢谢您的解释。有点帮助。然而,这就是我在JS中迷失的地方。当我打开这些链接时,我在控制台中寻找什么。控制台中不会自动显示任何内容。我遗漏了什么吗?试着在演示中点击Run按钮。你知道多少JavaScript?好吧,我想我知道了。我应该将一个控制台中的run
的结果(胖箭头保留上下文)与另一个控制台中的run
的结果(普通箭头丢失上下文)进行比较,因此在胖箭头中我得到C{m:function,m:function}
,但使用普通箭头,我得到的窗口作为上下文窗口{top:Window,Window:Window,location:location,external:Object,chrome:Object…}
。我读过很多JavaScript书籍和应用程序,但在复杂的应用程序中遇到困难,因此即使我理解这些基本点,我也很难在大型应用程序中跟踪这些细节。最基本的是,JavaScript函数中的这
取决于函数的调用方式,而不是函数的定义方式。当然,除了当然,在绑定函数的情况下。这就是为什么c.m()
和f()
在->
版本中有不同的行为,即使c.m
和f
是完全相同的函数。
something_that_calls_back(obj.each)