-2

当我在家里玩一些Javascriptz时,我遇到了一些事情......

我做了一个简单的函数,它从字符串中返回每个字符或从数组中返回每个位置值:

function each (haystack, callback) {
    var each;
    for (each in haystack){
        if (callback && typeof callback == "function") {
            callback (haystack[each]);
        }
    }
}

如何使用:

each ("StackOverflow", function (c) {
    console.log(c);
});

我想知道是否有办法将 /\ 变成这样:

each ("StackOverflow", c) {
    console.log(c);
}

或者至少是这样的,任何你不需要function为回调重写单词的东西。

我试过这个,但没有成功:

each ("StackOverflow",
    "console.log(c)" // turn the callback function into a string
    // but where was `c` defined here? do.not.ask.me.
);

并且each()是:

function each (haystack, callback) {
    var each;
    for (each in haystack){
        // call it in a setTimeout() crazy? yeah, didn't work...
        setTimeout(callback, 0);

        //and also tried this, no success...
        var b = new Function ("haystack[each]", cb);
        b ();
    }
}

我的结论是,不幸的是,如果不声明匿名函数,我们就不能拥有回调函数。

有没有办法在不使用工作的情况下制作回调函数 function

4

5 回答 5

4

请忘记字符串表示版本,它总是涉及eval(),我们知道这是邪恶的。

您不能简单地更改编程语言的语法。

无论如何,写作function () {}并不是什么大麻烦,您甚至可以将编辑器配置为自动插入片段。您还可以使用 CoffeeScript,它具有更简单的函数语法(当然,除了其他几个特性)并编译为 Javascript。

此外,您不必使用匿名函数。您可以传递任何类型的函数。

var func = function (x) { console.log(x); }; //inline function
each ("StackOverflow", func);

function func2 (x) { console.log(x); }; //classic function
each ("StackOverflow", func2);

each ("StackOverflow", alert); //YEEEES

each ("StackOverflow", 
    console.log.bind(console)); //here you should bind it to console!
于 2012-12-21T01:35:44.470 回答
3
for (each in haystack)

如果您希望haystack成为一个数组,则应该使用 for 循环对其进行迭代,而不是使用 for 循环枚举键(请参阅JavaScript for...in 与 for的区别)。如果您迭代字符串,尤其如此,请注意旧的 IE 不支持字符串上的括号表示法。

如果不声明匿名函数,我们就不能有回调函数

不,对于回调函数,我们当然需要一些函数。但它不一定必须是匿名函数表达式。在您的示例中,您可以这样做

each ("StackOverflow", console.log);
each ("StackOverflow", console.log.bind(console)); // for Chrome users

…或传递您在其他地方声明的任何其他合适的函数。

字符串(比如在这个库中)有时可能更短,但它们需要被eval编辑,这对这个目的来说是邪恶的。不幸的是,EcmaScript 不支持任何更短的 lambda 表达式,但是您可能想看看FF-only JavaScript 1.8表达式闭包CoffeeScript的极简函数语法。

于 2012-12-21T01:37:59.467 回答
3

在 ECMAScript 中创建函数有两种四种方式

  1. 函数声明
  2. 函数表达式
  3. 作为函数调用的 Function 构造函数
  4. 作为构造函数调用的 Function 构造函数

所有都需要使用字符串“function”或“Function”。

于 2012-12-21T01:39:27.620 回答
2

console.log直接用作回调,您必须确保将其绑定回console以免它丢失正确的执行上下文,至少在 Chrome 中是这样,所以我被告知:)

each([1, 2, 3], console.log.bind(console));

此外,您each()不能安全地使用它for ... in

for (var i = 0, n = haystack.length; i != n; ++i) {
    callback(haystack[i]);
}

当向对象添加额外的属性时,差异会更加明显Array

另请参阅:为什么在数组迭代中使用“for...in”是个坏主意?

于 2012-12-21T01:41:34.013 回答
2

简短的回答:没有。

您可以采用像Coffeescript这样的编译到 JavaScript 的语言,它对匿名函数有更短的语法:

//javascript version
function(c){ console.log(c) }

//coffeescript version
(c) => console.log c

否则,您将不得不在某处声明该函数,无论是“就地”(匿名函数)还是代码中的其他地方作为变量。

于 2012-12-21T01:40:40.320 回答