web-dev-qa-db-fra.com

`nouvelle fonction ()` avec des minuscules "f" en JavaScript

Mon collègue utilise "new function ()" avec un minuscule "f" pour définir de nouveaux objets en JavaScript. Il semble bien fonctionner dans tous les principaux navigateurs et il semble également assez efficace pour masquer les variables privées. Voici un exemple:

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

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

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

Dès que "this" est utilisé, il devient une propriété publique de someObj. Ainsi, someObj.foo, someObj.get_inner () et someObj.set_inner () sont tous disponibles publiquement. De plus, set_inner () et get_inner () sont des méthodes privilégiées, ils ont donc accès aux "internes" via des fermetures.

Cependant, je n'ai vu aucune référence à cette technique nulle part. Même JSLint de Douglas Crockford s'en plaint:

  • construction bizarre. Supprimer "nouveau"

Nous utilisons cette technique en production et elle semble bien fonctionner, mais je suis un peu inquiète car elle n'est documentée nulle part. Est-ce que quelqu'un sait si c'est une technique valable?

106
Johnny Oshika

J'ai déjà vu cette technique, elle est valide, vous utilisez une expression de fonction comme si c'était une fonction constructeur .

Mais à mon humble avis, vous pouvez obtenir la même chose avec une expression de fonction auto-invoquante, je ne vois pas vraiment l'intérêt d'utiliser l'opérateur new de cette façon:

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

Le but de l'opérateur new est de créer de nouvelles instances d'objets, en configurant [[Prototype]] propriété interne, vous pouvez voir comment cela est fait par le [Construct] propriété interne.

Le code ci-dessus produira un résultat équivalent.

64
CMS

Votre code est similaire à la construction la moins étrange

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

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

Pour clarifier certains aspects et empêcher JSLint de Douglas Crockford de se plaindre de votre code, voici quelques exemples d'instanciation:

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

Dans l'exemple 3. l'expression dans (...) as value est une fonction/constructeur. Il ressemble à ceci: new (function () {...}) (). Donc, si nous omettons les crochets de fin comme dans l'exemple 2, l'expression est toujours un appel de constructeur valide et ressemble à l'exemple 4.

JSLint de Douglas Crockford "pense" que vous vouliez assigner la fonction à someObj, pas son instance. Et après tout, ce n'est qu'un avertissement, pas une erreur.

12
DUzun