web-dev-qa-db-ja.com

JavaScriptで小文字の「f」を使用する `new function()`

私の同僚は、JavaScriptで新しいオブジェクトを定義するために、小文字の「f」で「new function()」を使用しています。それはすべての主要なブラウザでうまく機能するようであり、プライベート変数を隠すのにもかなり効果的であるようです。以下に例を示します。

    var someObj = new function () {
        var inner = 'some value';
        this.foo = 'blah';

        this.get_inner = function () {
            return inner;
        };

        this.set_inner = function (s) {
            inner = s;
        };
    };

「this」が使用されるとすぐに、someObjのパブリックプロパティになります。したがって、someObj.foo、someObj.get_inner()、およびsomeObj.set_inner()はすべて公開されています。さらに、set_inner()およびget_inner()は特権メソッドであるため、クロージャーを介して「内部」にアクセスできます。

しかし、私はこのテクニックへの言及をどこにも見ていません。ダグラス・クロックフォードのJSLintでさえ不満を述べています。

  • 奇妙な構造。 「新規」を削除

この手法を実稼働で使用しており、うまく機能しているように見えますが、どこにも文書化されていないため、少し心配です。これが有効な手法であるかどうかは誰にもわかりますか?

106
Johnny Oshika

私は前にそのテクニックを見ました、それは有効です、あなたはあたかもそれが Constructor Function であるかのように関数式を使用しています。

しかし、私見では、自動呼び出し関数式で同じことを達成できます。そのようにnew演算子を使用するポイントは実際にはわかりません。

var someObj = (function () {
    var instance = {},
        inner = 'some value';

    instance.foo = 'blah';

    instance.get_inner = function () {
        return inner;
    };

    instance.set_inner = function (s) {
        inner = s;
    };

    return instance;
})();

new演算子の目的は、新しいオブジェクトインスタンスを作成し、[[Prototype]]内部プロパティ。これが [Construct] 内部プロパティ。

上記のコードは同等の結果を生成します。

64
CMS

あなたのコードは、それほど奇妙ではない構造に似ています

function Foo () {
    var inner = 'some value';
    this.foo = 'blah';

    ...
};
var someObj = new Foo;
15
kennytm

いくつかの側面を明確にし、Douglas CrockfordのJSLintがあなたのコードについて文句を言わないようにするために、インスタンス化の例をいくつか示します。

1. o = new Object(); // normal call of a constructor

2. o = new Object;   // accepted call of a constructor

3. var someObj = new (function () {  
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
})(); // normal call of a constructor

4. var someObj = new (function () {  
    var inner = 'some value';
    this.foo = 'blah';

    this.get_inner = function () {
        return inner;
    };

    this.set_inner = function (s) {
        inner = s;
    };
}); // accepted call of a constructor

例3では、値としての(...)の式は関数/コンストラクターです。次のようになります:new(function(){...})()。したがって、例2のように終了括弧を省略すると、式は依然として有効なコンストラクター呼び出しであり、例4のようになります。

Douglas CrockfordのJSLintは、インスタンスではなくsomeObjに関数を割り当てたいと考えています。そして結局のところ、それは単なる警告であり、エラーではありません。

12
DUzun