【问题标题】:How to concisely assign and immediately invoke a function variable?如何简洁地分配并立即调用函数变量?
【发布时间】:2012-09-10 20:27:45
【问题描述】:

以下是在闭包中定义匿名函数,调用该函数,然后忘记它的方法:

(function () { "do stuff"; })();

这用于在不向脚本添加大量内容的情况下保持有限的范围(IIFE:立即调用函数表达式)。

如果您希望立即执行某个函数,同时仍保留该函数以供将来使用,该怎么办,如下所示:

var doThing;
(doThing = function () { "do stuff"; })();

这适用于我测试过的浏览器(Chrome、FF、IE8、IE10),但这并没有通过 JSLint(错误调用)。这样做有兼容性问题吗?

有没有一种被 JSLint 看好的方法来完成这个?

【问题讨论】:

  • 如果你的函数体是return 10;,那doThing不会被定义为10而不是函数本身吗?
  • @Cory 不,括号在作业周围。很容易测试,对吧?
  • @DaveNewton:啊,谢谢你指出这一点。

标签: javascript function jslint iife


【解决方案1】:

如果传递 jslint 是绝对必要的,那么:

var doThing;
(doThing = function () { "do stuff"; }).call();

应该做的工作。

编辑

.call期间传递参数

var doThing;
(doThing = function (param1, param2) { 'do stuff'; }).call(this, arg1, arg2);

【讨论】:

  • 太棒了!这是否真的有用仍然悬而未决,但这肯定回答了这个问题。谢谢!
  • 与:var doThing = function() { "do stuff"; }; doThing(); 的长度相同,但最终结果相同,但清晰度要低得多(但是是的,回答了问题)
  • 你是对的;这不切实际。最好尝试找到解决旧问题的新方法并失败,而不是始终使用您一直使用的相同方法。失败促进进步。
【解决方案2】:

对代码稍作重新排序会有所帮助。

var doThing = function () { "do stuff"; };
doThing();

var doThing = function () { "do stuff"; };
(doThing)();

【讨论】:

  • 这实际上略有不同......var doThing = function () { "do stuff"; }; doThing = doThing(); 将相当于 OP 正在寻找的内容。也就是说,这是一种尴尬且不标准的编写方式。
  • @JeremyJStarcher 他想立即调用一个函数,并将其保存以备将来使用。这正是我写的代码所做的......
  • @dqhendricks:但他也想“保持有限的范围”。您正在全局范围内执行doThing()
  • @Aejay 您可以从您的函数中返回 arguments.callee,这基本上会返回函数本身以执行您希望执行的操作,但正在讨论 arguments.callee 是否会在未来的 ECMA 脚本版本中是否已折旧。
  • @Aejay 基本上是var somefunction = ( function() { // do something; return arguments.callee; } )();
【解决方案3】:

您不应同时分配函数引用和调用函数。这种事情很容易导致人头爆炸,因为它会增加已经存在的将变量分配给引用、将变量分配给返回或将变量分配给赋值结果的可能性。这样做的任何其他人都能够阅读您的代码的方法是在 2 行中完成。如果你想把它包装在一个函数中,它会是这样的:

var doThing = (function() {
  var inner = function() {
     //doThing body
  };
  inner();
  return inner;
})();

这本身只会给您带来混淆,而不是以简单的方式进行操作,因为无论如何调用都不会保留。但是,如果您真的想要创建一个执行此操作的函数,您可以

var callAndRef = function(funk) {
  funk();
  return funk;
};

然后

var doThing = callAndRef(function() {
//doThing body
});

或者,如果您感觉更棒,并且有 JS 专家与您合作,您可以将其放到 Function.prototype 上并将其与声明链接起来。您还可以加入调用/申请以维护 this 引用和参数(但对于您当前的问题,这似乎只是噪音)。

所有这一切都应该非常谨慎地完成当然不值得走这条路,以免自己不得不每条命令多输入几行。

【讨论】:

  • 这个问题更多是出于好奇而不是实用性:)。我喜欢这个回答,但我认为 CD Sanchez 的代码更直接地回答了这个问题。不过,我很好奇一个人的表现如何。
  • 他最有可能表现得更好,更简洁。缺点是它利用了分配结果的优势,这在支持它的语言中通常似乎不鼓励,因为它极大地混淆了新手并且仍然可能使有经验的人绊倒。
  • +1,jslint 抱怨这行代码,因为它故意混淆。如果没有开发人员积极努力对其进行混淆,js 就足够狡猾了。
【解决方案4】:

如果您只想修复错误调用问题,您可以这样做:

var doThing;
doThing = function () { "do stuff"; };
doThing();

通过拆分声明和赋值,您可以使代码更易于理解和维护。另一种选择是声明一个具有名称的函数:

function doThing() { "do stuff"; }
doThing();

【讨论】:

    【解决方案5】:

    JSLink 是 Crawford 对如何编写 Javascript 的个人意见。其中大部分是极好的建议,但有时他的意见似乎会妨碍您。

    这是写那行的更“标准”的方式:

    var doThing = (function () { "do stuff"; }());
    

    注意整个(函数...)在括号内。

    【讨论】:

    • True Crockford 建议这样做,但它没有回答问题。如何调用并稍后调用它。
    • @epascarello -- 那我一定是误解了这个问题。
    • 'doThing' 不使用此代码绑定到函数。然而,我倾向于同意克劳福德的观点不应该被过于虔诚地对待。 OP 正在寻找从 doThing 中的函数保存闭包,并调用它(至少我是这样解释的)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 2021-08-31
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    相关资源
    最近更新 更多