JavaScript:按名称调用参数求值

JavaScript:按名称调用参数求值,javascript,Javascript,我编写了一个函数,它报告某个元素已加载: var reportLoaded = function(element) { $("<div>" + element + " loaded " + new Date().getMilliseconds() + "</div>").appendTo("body"); } 它不起作用,因为函数是直接求值的 所以我不得不这样做: var reportLoadedDelayed = function

我编写了一个函数,它报告某个元素已加载:

var reportLoaded = function(element) {
    $("<div>" + element + " loaded " + new Date().getMilliseconds() 
              + "</div>").appendTo("body");
}
它不起作用,因为函数是直接求值的

所以我不得不这样做:

var reportLoadedDelayed = function(element) {
    return function() {
        reportLoaded(element);
    }   
}

$(document).ready(reportLoadedDelayed("document"))
是否有一个简短的符号来指定要按名称计算参数?与Scala一样,您可以声明一个函数:

def lazyEval(x: => Int) = {println("lazy"); x;}
// Best to have this in a scoping function
var slice = Array.prototype.slice;
Function.prototype.curry = function() {
    var args =  slice.call(arguments, 0);
    args.unshift(null);
    return this.bind.apply(this, args);
};
如果需要的话,x将在实际需要的时候进行计算

但当我将此函数附加到例如jQuery的ready方法时:

$(文档).ready(已加载报表(“文档”))

它不会将其附加到
ready
。它调用
reportLoaded(“document”)
并将其返回值传递到
ready
,就像
foo(bar())
调用
bar
并将其返回值传递到
foo
一样

如果要实际传入函数引用,请使用函数表达式或,它可用于转换参数:

$(document).ready(function() {
    reportLoaded("document");
});

或者实际上,jQuery有:


如果您经常这样做,您可以通过给自己一个
curry
函数,摆脱一直键入
null
的需要:

def lazyEval(x: => Int) = {println("lazy"); x;}
// Best to have this in a scoping function
var slice = Array.prototype.slice;
Function.prototype.curry = function() {
    var args =  slice.call(arguments, 0);
    args.unshift(null);
    return this.bind.apply(this, args);
};


请注意,
Function#bind
在ES5(2009)中是“新的”,但如果需要支持IE8等较旧的浏览器,则可以轻松填充。

Javascript中没有lambda表达式,最接近的是函数表达式:

$(document).ready(function(){ reportLoaded("document"); });
还可以使用从函数标识符创建函数,并将参数绑定到该函数:

$(document).ready($.proxy(reportLoaded, this, "document"));

您可以使用
$(document).ready(函数(){reportLoaded(“document”);})是的,但是每次手动编写都很乏味,所以我想可能会有一些语法上的甜点。你可以用
$(function(){})
而不是
$(document)。ready(function(){})
。@T.J.Crowder,我刚才在你的问题下键入了一条注释,但你在这里回答了。非常感谢。这是
函数表达式
与调用
reportLoaded
的匿名函数相同,还是这是一种特殊的JavaScript语法,不需要两次函数调用?@maja:我不理解这个问题。没有“特殊”的JavaScript语法;只有JavaScript语法。JavaScript语法的一个方面是,您可以拥有函数表达式,并且它们可以是匿名的。上面的那个是匿名的。JavaScript还具有命名函数表达式,以及单独的函数声明(必须始终具有名称)。很快(ES6)它也会有arrow函数声明。我的问题是(或曾经是),ready事件是否会首先调用匿名函数,然后调用实际的
reportLoaded
-函数,或者规范是否声明“在这种情况下,仅调用内部函数,出于性能原因,将放弃匿名函数”。(忽略非标准浏览器优化的可能性)@maja:当我们执行
ready
行时,实际上只执行
ready
。稍后,当jQuery决定DOM就绪时,它将调用匿名函数,该函数将调用
reportLoaded
。当然,JavaScript引擎可以自由优化,前提是这样做不会产生超出规范的副作用,b但是这在这里会很尴尬,而且通常规范(从ES5开始)没有进入优化。谢谢,这回答了我的问题。
$(document).ready($.proxy(reportLoaded, this, "document"));