什么';现在javascript匿名函数中的“return function()”是怎么回事?(最佳做法) 注:更新和重写

什么';现在javascript匿名函数中的“return function()”是怎么回事?(最佳做法) 注:更新和重写,javascript,Javascript,此问题已被重做并更新。请原谅下面过时的参考资料。 谢谢 我最近看到很多javascript代码在我看来是错误的。在这种情况下,我应该推荐什么作为更好的代码模式?我将重现我所看到的代码,并对每个代码进行简短描述: 代码块#1 此代码不应计算内部函数。程序员会感到困惑,因为代码应该运行 $(document).ready( function() { return function() { /* NOPs */ } }); 代码块#2 程序员可能打算实现一个自调用函数。他们没有完

此问题已被重做并更新。请原谅下面过时的参考资料。 谢谢

我最近看到很多javascript代码在我看来是错误的。在这种情况下,我应该推荐什么作为更好的代码模式?我将重现我所看到的代码,并对每个代码进行简短描述:

代码块#1 此代码不应计算内部函数。程序员会感到困惑,因为代码应该运行

$(document).ready( function() { 
  return function() { 
    /* NOPs */
  }
});
代码块#2 程序员可能打算实现一个自调用函数。他们没有完全完成实现(他们在嵌套参数的末尾缺少一个
()
。此外,因为他们没有在外部函数中执行任何操作,所以嵌套的自调用函数可能只是内联到外部函数定义中

事实上,我不知道他们想要一个自调用函数,因为代码仍然是错误的。但是看起来他们想要一个自调用函数

$(document).ready( (function() { 
  return function() { 
    /* NOPs */
  }
}));
代码块#3 程序员似乎再次尝试使用一个自调用函数。然而,在这种情况下,这是过分的

$(document).ready( function() { 
  (return function() { 
    /* NOPs */
  })()
}); 
代码块#4 示例代码块

$('#mySelector').click( function(event) { 
  alert( $(this).attr('id') );

  return function() { 
    // before you run it, what's the value here?
    alert( $(this).attr('id') );
  }
});
评论: 我想我只是感到沮丧,因为它会导致人们不理解的爬行bug,改变他们没有摸索的范围,通常会产生非常奇怪的代码。这些都是来自某个地方的教程吗?如果我们要教人们如何编写代码,我们能教他们正确的方法吗

你会建议什么作为一个准确的教程来向他们解释为什么他们使用的代码是不正确的?你会建议他们学习什么模式


我所看到的所有导致我提出这个问题的示例都是以问题的形式出现的。下面是我遇到的最新一个展示这种行为的特定片段。您会注意到,我没有发布问题的链接,因为用户似乎是新手

$(document).ready(function() {
 $('body').click((function(){
  return function()
  {
   if (counter == null) {
    var counter = 1;
   }
   if(counter == 3) {
     $(this).css("background-image","url(3.jpg)");
     $(this).css("background-position","10% 35%");
     var counter = null;
   }
   if(counter == 2) {
     $(this).css("background-image","url(2.jpg)");
     $(this).css("background-position","10% 35%");
     var counter = 3;
   }
   if(counter == 1) {
     $(this).css("background-image","url(1.jpg)");
     $(this).css("background-position","40% 35%");
     var counter = 2;
   }


  }
 })());
});
下面是我建议他们重写代码的方式:

var counter = 1;
$(document).ready(function() {
    $('body').click(function() {
        if (counter == null) {
            counter = 1;
        }
        if (counter == 3) {
            $(this).css("background-image", "url(3.jpg)");
            $(this).css("background-position", "10% 35%");
            counter = 1;
        }
        if (counter == 2) {
            $(this).css("background-image", "url(2.jpg)");
            $(this).css("background-position", "10% 35%");
            counter = 3;
        }
        if (counter == 1) {
            $(this).css("background-image", "url(1.jpg)");
            $(this).css("background-position", "40% 35%");
            counter = 2;
        }
    });
});
请注意,我并不是说我的代码在任何方面都更好。我只是删除了匿名中介函数。我实际上知道为什么这段代码最初没有达到他们想要的效果,我也不想重写每个人的代码,但我确实希望chap至少有可用的代码


我想如果你真的想要这个问题的链接,请给我发一个gmail。他得到了几个非常好的答案,其中我的答案最好是中级。我想很多人都会同意你的观点,那就是有时候尝试和太可爱是不好的。如果你不需要的话一个语言结构,然后不要使用它,特别是如果它是混乱的

也就是说,有时候你确实需要这些东西

(function(){
    var x = 'test';
    alert(x);
})()

alert(typeof(x)); //undefined
这里,x变量被锁定在函数范围内

(我在网站上找到了上述示例)


所以,你可以用javascript在scope上做一些奇怪的事情;这是一种方法。我同意你的观点,很多js代码比它需要的复杂得多。

匿名函数对于:

  • 将逻辑传递给另一个函数
  • 声明一次性使用函数
  • 在不向作用域添加变量的情况下声明函数
  • 为变量提供作用域
  • 动态规划

您可以在以下链接上阅读更多关于这些主题的内容:

它们都是javascript闭包的形式,如果发生异步调用,它们通常是在函数最终被调用时,在适当范围内获得正确变量值的唯一方法

有关示例/说明,请参见:


您的第一个示例很奇怪。我甚至不确定这是否符合作者的意图。第二个示例只是将第一个示例包装在不必要的括号中。第三个示例使用了自调用函数,尽管由于匿名函数创建了自己的作用域(可能还有一个闭包),但我不确定它有什么好处(除非作者在闭包中指定了其他变量-请继续阅读)

自调用函数采用模式
(函数f(){/*do stuff*/}())
,并立即进行计算,而不是在调用时进行计算。因此类似于以下内容:

var checkReady = (function () {
    var ready = false;
    return {
        loaded: function () { ready = true; },
        test: function () { return ready; }
    };
}())
$(document).ready(checkReady.loaded);
创建一个闭包,将作为
checkready
返回的对象绑定到变量
ready
(该变量对闭包之外的所有内容都隐藏)。这将允许您通过调用
checkready.test()来检查文档是否已加载(根据jQuery)
。这是一个非常强大的模式,有很多合法的用途(名称空间、记忆、元编程),但在您的示例中并不是必需的

编辑:啊,我误解了你的问题。我不知道你是在呼吁不良做法,而不是要求对模式进行澄清。更多关于你所问的最终形式:

(function () { /* woohoo */ }())
(function () { /* woohoo */ })()
function () { /* woohoo */ }()

评估结果大致相同-但第一种形式最不可能产生任何意外后果。

我不确定您是否完全重新创建示例,但为了这个

// I picked document ready from jQuery cos you ALL know it, I'm sure ;) 
$('#mySelector').click( function(event) { // this line is all boilerplate, right? 
  alert( $(this).attr('id') ); 

  return function() { // <-- WHAT THE ???? IS THIS ????  ? 
    // before you run it, what's the value here? 
    alert( $(this).attr('id') ); 
  } 
}); 
外部函数将在我们附加事件处理程序时执行。第一个警报将在该时间发生,以及在同一范围内进行的任何其他准备。结果是生成在“onclick”期间激发的实际方法,这是内部函数,在准备阶段也可以访问数据


我可以看出这在某些情况下是合适的,尽管它看起来相当复杂。对于前一个例子,我假设程序员不知道他们在做什么。

对于代码块一,这看起来有点像我见过的用于具有私有
// I picked document ready from jQuery cos you ALL know it, I'm sure ;) 
$('#mySelector').click( function(event) { // this line is all boilerplate, right? 
  alert( $(this).attr('id') ); 

  return function() { // <-- WHAT THE ???? IS THIS ????  ? 
    // before you run it, what's the value here? 
    alert( $(this).attr('id') ); 
  } 
}() ); 
function MyObject()  {
   var privateMember = 1;

   return {
        "Add":function(x) {return x + privateMember;},
        "SetPrivateMember":function(x) {privateMember = x;},
        "GetPrivateMember":privateMember
   };
}
$(document).ready(function() {
    for (var i = 9; i <= 10; i++) {
        $('#button'+i).click(function() {
            alert('Button '+i+' clicked');
        });
    }
});
$(document).ready(function() {
    for (var i = 9; i <= 10; i++) {
        (function() {
            var j = i;
            $('#button'+j).click(function() {
                alert('Button '+j+' clicked');
            });
        })();
    }
});