首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >现在javascript匿名函数中的‘`return function()’是怎么回事?(最佳实践)

现在javascript匿名函数中的‘`return function()’是怎么回事?(最佳实践)
EN

Stack Overflow用户
提问于 2010-10-16 03:02:35
回答 5查看 5.9K关注 0票数 16

注意:更新和重写

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

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

代码块#1

这段代码永远不应该计算内部函数。程序员会感到困惑,因为代码应该运行。

代码语言:javascript
复制
$(document).ready( function() { 
  return function() { 
    /* NOPs */
  }
});

代码块#2

程序员可能打算实现自调用函数。他们没有完全完成实现(他们在嵌套的paren的末尾缺少一个()。此外,因为它们不会在外部函数中做任何事情,所以嵌套的自调用函数可以内联到外部函数定义中。

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

代码语言:javascript
复制
$(document).ready( (function() { 
  return function() { 
    /* NOPs */
  }
}));

代码块#3

同样,程序员似乎正在尝试使用自调用函数。然而,在这种情况下,它是过度杀伤力。

代码语言:javascript
复制
$(document).ready( function() { 
  (return function() { 
    /* NOPs */
  })()
}); 

代码块#4

示例代码块

代码语言:javascript
复制
$('#mySelector').click( function(event) { 
  alert( $(this).attr('id') );

  return function() { 
    // before you run it, what's the value here?
    alert( $(this).attr('id') );
  }
});

评论:

我猜我只是感到沮丧,因为它导致了人们不理解的爬行bug,改变了他们不熟悉的范围,并且通常会产生非常奇怪的代码。这些都来自于某处的一些教程吗?如果我们要教人们如何写代码,我们能教他们正确的方式吗?

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

我看到的所有导致我问这个问题的样本都是这样的问题。这是我遇到的展示这种行为的最新代码片段。你会注意到,我并没有张贴这个问题的链接,因为这个用户看起来是个新手。

代码语言:javascript
复制
$(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;
   }


  }
 })());
});

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

代码语言:javascript
复制
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;
        }
    });
});

请注意,我实际上并不是说我的代码在任何方面都更好。我只删除了匿名中介函数。我实际上知道为什么这段代码最初不能做他们想要的事情,我也不想重写每个人的代码,但我确实希望这个家伙至少有可用的代码。

我认为一个真正的代码样本会很受欢迎。如果你真的想要这个特殊问题的链接,请在这个nick给我发gmail。他得到了几个非常好的答案,其中我的最好的答案是中级。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-10-16 03:18:33

你的第一个例子很奇怪。我甚至不确定这是否会像作者预期的那样工作。第二个简单地将第一个包含在不必要的括号中。第三个使用自调用函数,但是由于匿名函数创建了自己的作用域(可能还有一个闭包),我不确定它有什么用处(除非作者在闭包中指定了额外的变量-请继续阅读)。

自调用函数采用模式(function f () { /* do stuff */ }()),并立即进行计算,而不是在调用时进行计算。所以就像这样:

代码语言:javascript
复制
var checkReady = (function () {
    var ready = false;
    return {
        loaded: function () { ready = true; },
        test: function () { return ready; }
    };
}())
$(document).ready(checkReady.loaded);

创建一个闭包,将作为checkready返回的对象绑定到变量ready (闭包之外的所有内容都看不到它)。这将允许您通过调用checkReady.test()检查文档是否已加载(根据jQuery)。这是一个非常强大的模式,有很多合法的用法(命名空间、记忆化、元编程),但在您的示例中并不是必需的。

编辑:啊,我误解了你的问题。我没有意识到你是在呼吁糟糕的实践,而不是要求对模式进行澄清。更多关于你所问的最终表单的要点:

代码语言:javascript
复制
(function () { /* woohoo */ }())
(function () { /* woohoo */ })()
function () { /* woohoo */ }()

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

票数 9
EN

Stack Overflow用户

发布于 2010-10-16 03:07:09

我想很多人会同意你的观点,有时尝试和太可爱是不好的。如果你不需要语言结构,那么就不要使用它,特别是当它令人困惑的时候。

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

代码语言:javascript
复制
(function(){
    var x = 'test';
    alert(x);
})()

alert(typeof(x)); //undefined

在这里,x变量被锁定到函数作用域中。

(我在http://helephant.com/2008/08/javascript-anonymous-functions/找到了上面的例子)

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

票数 1
EN

Stack Overflow用户

发布于 2010-10-16 03:39:32

我不确定您是否准确地重新创建了您的示例,但是为了这个

代码语言:javascript
复制
// 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') ); 
  } 
}); 

正如您的第一个示例一样,返回的anon函数永远不会运行。如果在这里返回false而不是函数,则默认操作将被阻止。因此,我猜浏览器会将其评估为event handler returned truish

如果它被改成这样

代码语言:javascript
复制
// 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‘期间触发的实际方法,该方法是内部函数,在准备阶段也可以访问数据。

我认为这在某些情况下是合适的,尽管它看起来相当复杂。至于前面的例子,我假设你的程序员不知道他们在做什么。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3945259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档