8

私は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」を呼び出す方法はありますか?

4

8 に答える 8

9

何らかの方法で関数を公開する場合のみ。たとえば、外部関数から返すことができます。

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();

関数内で宣言された関数と変数は、何かを返すか、その関数の外で宣言された変数への参照を与えることによってそれらにアクセスする何らかの手段を提供しない限り、その関数の外から直接到達することはできません。

于 2013-01-09T20:21:19.880 に答える
5

これを行う可能性のある他のクラスまたは関数の名前空間を作成します。グローバルな名前空間を継続的に汚染したくはありませんが、グローバルな名前空間を 1 つ作成して、その下に個々のものを配置できない理由はありません。

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

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

MyNamespace.x()
于 2013-01-09T20:27:11.667 に答える
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/

于 2013-01-09T20:20:12.803 に答える
1

はい、(1つの方法は次のとおりです:)returnステートメントを使用してIIFEから返すだけです。また、変数をIIFEに割り当ててリターンを「キャッチ」する必要があります

var foo = (function(){

    return your_function;

}());
于 2013-01-09T20:20:29.587 に答える
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();

私たちが使用するパターンはわずかに優れています。

1 つのグローバル オブジェクト (つまり名前空間) があり、IIFE を含む js ファイルをインポートしてモジュールを追加します。

各 IIFE は、単一のグローバル オブジェクトに新しいモジュールを追加します。

これにより、プロジェクト全体でグローバル オブジェクトが 1 つだけになり、必要に応じてファイルをインクルードすることで任意のモジュールを利用できるようになります。

この記事は、JavaScript モジュール パターンに関する優れた議論です。

于 2013-01-09T20:31:47.983 に答える
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

于 2013-01-09T20:30:06.887 に答える
0

クロージャーの目的の 1 つは、スコープを制限することです。そのため、x()は定義されており、すぐに呼び出される関数式の内部で呼び出すことができますが、外部では未定義です。

コードをリファクタリングせずに機能させるには、関数ステートメント関数演算子を区別する JS 文法を利用できます。どちらも意味的には同じですが、後者はシナリオに適した変数に割り当てることができます。

var x; //scoped *outside* of the closure
(function ($) {
  var message = 'x called';
  x = function() {
    alert(message);
  }
})(jQuery);
x(); //alerts 'x called'
于 2013-01-09T22:34:09.563 に答える