可以在立即调用的函数表达式中调用JavaScript函数

时间:2013-01-09 20:18:10

标签: javascript jquery html html5

我正在使用jQuery并在一个立即调用的函数表达式中包含一个函数,如下所示:

<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    (function ($) {

        var message = 'x called';

        function x() {
            alert(message);
        }
    })(jQuery);

    x();
</script>

这将导致错误,因为函数“x”未在立即调用的函数表达式之外定义。有没有办法在立即调用的函数表达式之外调用函数“x”?

8 个答案:

答案 0 :(得分:8)

仅当您以某种方式公开该功能时。例如,您可以从外部函数返回它:

var x = (function ($) {

    var message = 'x called';

    function x() {
        alert(message);
    }

    return x;
})(jQuery);

x();

或者,类似地,您可以将其返回到对象上:

var obj = (function ($) {

    var message = 'x called';

    function x() {
        alert(message);
    }

    return {"x": x};
})(jQuery);

obj.x();

函数内部声明的函数和变量不能直接从该函数外部访问,除非您通过返回某些内容提供一些访问它们的方法,或者提供对该函数外部声明的变量的引用。

答案 1 :(得分:4)

为您可能想要执行此操作的其他类或函数创建命名空间。您不希望不断污染全局命名空间,但是没有理由不能创建一个全局命名空间并将您的个人事物置于其下面:

(function($){
  window.MyNamespace = function(){};
  var message = "Something here";

  $.extend(MyNamespace, {
    x: function(){
      alert(message);
    }
  });
})(jQuery)

MyNamespace.x()

答案 2 :(得分:2)

您可以按如下方式更改代码:

<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
<script type="text/javascript">
    var x;
    (function ($) {

        var message = 'x called';

        x = function () {
            alert(message);
        }
    })(jQuery);

    x();
</script>

jsFiddle链接:http://jsfiddle.net/aLnbn/

答案 3 :(得分:1)

是的,(一种方法是:)只需使用return语句从IIFE返回它,你也需要通过为IIFE分配变量来“捕获”返回

var foo = (function(){

    return your_function;

}());

答案 4 :(得分:1)

您可以使用IIFE返回(或扩充)全局变量来访问您的方法。

你可以这样做:

var globalObject = (function (theObject, $) {

        if (theObject.theMethod) {
            return theObject;
        }

        var message = 'theMethod called';

        theObject.theMethod = function () {
            alert(message);
        };

        return theObject;

})(globalObject || {}, jQuery);


globalObject.theMethod();

我们使用的模式略好一些。

我们有一个全局对象(即名称空间),我们通过导入包含IIFE的js文件为其添加模块。

每个IIFE都会为单个全局对象添加一个新模块。

这使得我们整个项目只有一个全局对象,可以通过包含文件来选择性地利用我们的任何模块。

我建议查看这篇文章,这是关于JavaScript模块模式的一个很好的讨论:

答案 5 :(得分:0)

试试这个:

var miFunc = (function($) {
    var message = 'x called';
    function x() {
        console.log(message);
    }
    this.x = x;
    return this;
})(jQuery);
miFunc.x();

测试:http://jsbin.com/erucix/2/edit

答案 6 :(得分:0)

关闭的目的之一是限制范围。这就是定义x()并且可以在立即调用的函数表达式中调用但在外部未定义的原因。

为了使您的代码无需重构,您可以利用JS语法来区分a function statementa function operator。两者在语义上是相同的,但后者可以分配给适合您的场景的变量:

var x; //scoped *outside* of the closure
(function ($) {
  var message = 'x called';
  x = function() {
    alert(message);
  }
})(jQuery);
x(); //alerts 'x called'

答案 7 :(得分:0)

您可以使用IIFE返回全局变量来访问您的方法。

//IIFEs - Immediately Invoked Function Expressions
var namespaceTestIIFE = (function ($) {

    /** Public functions and state. */
    var pub = {};

    $(document).ready(function () {
        //your on ready logic
    });

    pub.testAlert = function () {
       alert('Hello TestAlert');
    }
    return pub;
})(jQuery);

OR

var compareForm = (function ()
{
        /** Public functions and state. */
        var pub = {};
        pub.testAlert = function () {
           alert('Hello TestAlert');
        }
    return pub;
}());

访问函数使用&#34; namespace.functionname&#34;例如 -

namespaceTestIIFE.testAlert();