Auto-références dans les littéraux / initialiseurs d'objets

705

Existe-t-il un moyen de faire fonctionner quelque chose comme le suivant en JavaScript?

var foo = {
    a: 5,
    b: 6,
    c: this.a + this.b  // Doesn't work
};

Dans le formulaire actuel, ce code renvoie évidemment une erreur de référence car thisil ne fait pas référence à foo. Mais existe- t - il un moyen de faire en sorte que les valeurs des propriétés d'un littéral d'objet dépendent d'autres propriétés déclarées précédemment?

kpozin
la source

Réponses:

744

Eh bien, la seule chose dont je peux vous parler est getter :

var foo = {
  a: 5,
  b: 6,
  get c() {
    return this.a + this.b;
  }
}

console.log(foo.c) // 11

Il s'agit d'une extension syntaxique introduite par la spécification ECMAScript 5e édition, la syntaxe est prise en charge par la plupart des navigateurs modernes (y compris IE9).

CMS
la source
32
Réponse très utile. Plus d'informations sur 'get' peuvent être trouvées ici: developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/…
jake
5
@FaustoR. Oui.
Charlie Martin
48
Sachez qu'avec cette solution, si les valeurs de foo.aou foo.bsont modifiées, la valeur de foo.cchangera également en synchronisme. Cela peut ou non être ce qui est requis.
HBP
8
Notez que thisse lie à l'objet imbriqué le plus profond. Par exemple:... x: { get c () { /*this is x, not foo*/ } } ...
Z. Khullah
3
Pour compléter ma déclaration ci-dessus, étant donné qu'elle fooest déclarée en tant que variable et cne sera évaluée qu'au moment où elle est invoquée, l'utilisation de fooinside cfonctionnera, contrairement à this(soyez prudent cependant)
Z. Khullah
316

Vous pourriez faire quelque chose comme:

var foo = {
   a: 5,
   b: 6,
   init: function() {
       this.c = this.a + this.b;
       return this;
   }
}.init();

Ce serait une sorte d'initialisation unique de l'objet.

Notez que vous affectez réellement la valeur de retour de init()à foo, vous devez donc le faire return this.

Felix Kling
la source
95
vous pouvez aussi delete this.initavant return thispour que ce foone soit pas poli
Billy Moon
15
@BillyMoon: Oui en effet, bien que cela ait un impact sur les performances de tous les accès aux propriétés ultérieurs sur cet objet, sur de nombreux moteurs (V8, par exemple).
TJ Crowder
8
@MuhammadUmer: Je ne sais pas comment les classes ES6 sont pertinentes pour la question.
Felix Kling
8
@MuhammadUmer: les classes ne sont que du sucre syntaxique pour les fonctions constructeurs, donc elles ne fournissent vraiment rien de nouveau. Quoi qu'il en soit, l'objectif principal de cette question sont les littéraux d'objets.
Felix Kling
3
@akantoword: Great :) puisque les littéraux d'objet sont une seule expression, l' init()appel a été directement ajouté au littéral pour qu'il reste une seule expression. Mais bien sûr, vous pouvez appeler la fonction séparément de ce que vous voulez.
Felix Kling
181

La réponse évidente et simple manque, donc pour être complet:

Mais existe- t - il un moyen de faire en sorte que les valeurs des propriétés d'un littéral d'objet dépendent d'autres propriétés déclarées précédemment?

Non. Toutes les solutions ici le reportent jusqu'à la création de l'objet (de diverses manières), puis affectent la troisième propriété. La façon la plus simple est de le faire:

var foo = {
    a: 5,
    b: 6
};
foo.c = foo.a + foo.b;

Tous les autres sont simplement des moyens plus indirects de faire la même chose. (Felix est particulièrement intelligent, mais nécessite la création et la destruction d'une fonction temporaire, ajoutant de la complexité; et laisse soit une propriété supplémentaire sur l'objet ou [si vous deletecette propriété] a un impact sur les performances des accès ultérieurs à la propriété sur cet objet.)

Si vous avez besoin que tout soit dans une même expression, vous pouvez le faire sans la propriété temporaire:

var foo = function(o) {
    o.c = o.a + o.b;
    return o;
}({a: 5, b: 6});

Ou bien sûr, si vous devez le faire plusieurs fois:

function buildFoo(a, b) {
    var o = {a: a, b: b};
    o.c = o.a + o.b;
    return o;
}

alors où vous devez l'utiliser:

var foo = buildFoo(5, 6);
TJ Crowder
la source
Pour ma propre raison, j'essaie de trouver une sorte de documentation officielle qui dit essentiellement la même chose - qu'un objet thisn'est disponible que pour les méthodes dudit objet, et pas d'autres types de propriétés. Une idée où je pourrais trouver ça? Merci!
David Kennell
1
@DavidKennell: N'obtient pas plus officiel que la spécification . :-) Vous commenceriez probablement ici et le suivriez. C'est un langage assez gênant, mais fondamentalement, vous verrez dans les divers paragraphes de l' évaluation de la définition de propriété que l'objet n'est pas disponible pour les opérations déterminant les valeurs des initialiseurs de propriété.
TJ Crowder
Je ne peux pas voir les résultats du navigateur ici , mais ce n'est plus le cas non? Dans mon environnement, v8: deleteest 10% plus rapide et gecko: deleten'est que 1% plus lent.
TheMaster
1
@TheMaster - Oui, je ne pense plus que BrowserScope soit vraiment une chose. Il semble que la suppression ne soit pas aussi mauvaise qu'auparavant, du moins pas dans V8 (Chrome, etc.) ou SpiderMonkey. Toujours plus lent, mais seulement un tout petit peu, et ces choses sont très rapides ces jours-ci.
TJ Crowder
63

Instanciez simplement une fonction anonyme:

var foo = new function () {
    this.a = 5;
    this.b = 6;
    this.c = this.a + this.b;
};
zzzzBov
la source
1
@Bergi, pourquoi? Parce que quelqu'un pourrait en instancier un autre du même objet? Ce n'est pas comme s'ils ne pouvaient pas simplement cloner un objet littéral. Ce n'est pas différent que de passer un argument comme, new Point(x, y)sauf que la fonction n'est pas nommée pour être réutilisée.
zzzzBov
1
@zzzzBov: Bien sûr, ils peuvent simplement cloner l'objet, mais par rapport à une solution IEFE (comme dans la réponse de TJCrowder), votre solution fuit la fonction constructeur et crée un objet prototype superflu.
Bergi
5
@zzzzBov: Utilisez simplement var foo = function() { this.…; return this; }.call({});ce qui n'est pas très différent sur le plan syntaxique mais sémantiquement sain.
Bergi
1
@Bergi, si vous pensez que c'est si important, pourquoi ne pas ajouter votre propre réponse au mix?
zzzzBov
3
Vous avez ça. Je n'ai en effet pas remarqué le newmot - clé.
Randy
26

Maintenant, dans ES6, vous pouvez créer des propriétés mises en cache paresseux. Lors de la première utilisation, la propriété est évaluée une fois pour devenir une propriété statique normale. Résultat: la deuxième fois que la surcharge de la fonction mathématique est ignorée.

La magie est dans le getter.

const foo = {
    a: 5,
    b: 6,
    get c() {
        delete this.c;
        return this.c = this.a + this.b
    }
};

Dans la flèche, le getter thisreprend la portée lexicale environnante .

foo     // {a: 5, b: 6}
foo.c   // 11
foo     // {a: 5, b: 6 , c: 11}  
voscausa
la source
1
es5 possède également des propriétés que vous devez simplement utiliser Object.defineProperty(foo, 'c', {get:function() {...}})pour les définir. Cela se fait facilement de manière discrète dans une usine comme celle-ci. Bien sûr, si vous pouvez utiliser le getsucre, il est plus lisible, mais la capacité est là.
Aluan Haddad
21

Une fermeture devrait régler ce problème;

var foo = function() {
    var a = 5;
    var b = 6;
    var c = a + b;

    return {
        a: a,
        b: b,
        c: c
    }
}();

Toutes les variables déclarées dans foosont privées foo, comme vous vous en doutez avec n'importe quelle déclaration de fonction et parce qu'elles sont toutes de portée, elles ont toutes accès les unes aux autres sans avoir besoin de s'y référer this, tout comme vous vous attendriez avec une fonction. La différence est que cette fonction renvoie un objet qui expose les variables privées et affecte cet objet à foo. En fin de compte, vous retournez uniquement l'interface que vous souhaitez exposer en tant qu'objet avec l' return {}instruction.

La fonction est ensuite exécutée à la fin avec le ()qui provoque l'évaluation de l'ensemble de l'objet foo, toutes les variables dans instancié et l'objet de retour ajouté en tant que propriétés de foo().

Henry Wrightson
la source
14
Il est déroutant et trompeur d'appeler cela une "fermeture". Bien que les opinions divergent sur le sens précis de renvoyer une valeur d'objet d'une fonction ne constitue pas une clôture dans le livre de quiconque.
16

Tu pourrais le faire comme ça

var a, b
var foo = {
    a: a = 5,
    b: b = 6,
    c: a + b
}

Cette méthode s'est avérée utile lorsque j'ai dû me référer à l'objet sur lequel une fonction a été déclarée à l'origine. Voici un exemple minimal de la façon dont je l'ai utilisé:

function createMyObject() {
    var count = 0, self
    return {
        a: self = {
            log: function() {
                console.log(count++)
                return self
            }
        }
    }
}

En définissant self en tant qu'objet contenant la fonction d'impression, vous autorisez la fonction à se référer à cet objet. Cela signifie que vous n'aurez pas à «lier» la fonction d'impression à un objet si vous devez la transmettre ailleurs.

Si vous préférez, utilisez thiscomme illustré ci-dessous

function createMyObject() {
    var count = 0
    return {
        a: {
            log: function() {
                console.log(count++)
                return this
            }
        }
    }
}

Ensuite, le code suivant enregistrera 0, 1, 2, puis donnera une erreur

var o = createMyObject()
var log = o.a.log
o.a.log().log() // this refers to the o.a object so the chaining works
log().log() // this refers to the window object so the chaining fails!

En utilisant la méthode self, vous garantissez que print renverra toujours le même objet quel que soit le contexte dans lequel la fonction est exécutée. Le code ci-dessus fonctionnera très bien et enregistrera 0, 1, 2 et 3 lors de l'utilisation de la version autonome de createMyObject().

davedambonite
la source
3
De bons exemples, sauf que vous avez omis tous les points-virgules.
1
Pas de points - virgules - C'est la fin Vraiment!
Kerem Baydoğan
9

Pour l'achèvement, dans ES6, nous avons des classes (prises en charge au moment de l'écriture uniquement par les derniers navigateurs, mais disponibles dans Babel, TypeScript et autres transpilers)

class Foo {
  constructor(){
    this.a = 5;
    this.b = 6;
    this.c = this.a + this.b;
  }  
}

const foo = new Foo();
monzonj
la source
7

Vous pouvez le faire en utilisant le modèle de module. Juste comme:

var foo = function() {
  var that = {};

  that.a = 7;
  that.b = 6;

  that.c = function() {
    return that.a + that.b;
  }

  return that;
};
var fooObject = foo();
fooObject.c(); //13

Avec ce modèle, vous pouvez instancier plusieurs objets foo selon vos besoins.

http://jsfiddle.net/jPNxY/1/

Rafael Rocha
la source
2
Ce n'est pas un exemple du modèle de module, juste une fonction. Si la dernière ligne de la définition foo était }();, elle s'exécuterait automatiquement et retournerait un objet, pas une fonction. En outre, foo.cest une fonction, donc y écrire écrase cette fonction et la prochaine invocation via fooObject.c()échouera. Peut-être que ce violon est plus proche de ce que vous recherchez (c'est aussi un singleton, non conçu pour être instancié).
Hollister
2
"Le modèle de module a été initialement défini comme un moyen de fournir à la fois l'encapsulation privée et publique pour les classes en génie logiciel conventionnel". De: Apprendre les modèles de conception JavaScript . Cet objet suit le modèle de module décrit ci-dessus, mais ce n'est peut-être pas le meilleur pour expliquer cela car il n'affiche pas les propriétés / méthodes publiques et privées. Celui-ci jsfiddle.net/9nnR5/2 est le même objet avec des propriétés / méthodes publiques et privées. Donc, les deux suivent ce modèle
Rafael Rocha
6

Il existe plusieurs façons d'y parvenir; voici ce que j'utiliserais:

function Obj() {
 this.a = 5;
 this.b = this.a + 1;
 // return this; // commented out because this happens automatically
}

var o = new Obj();
o.b; // === 6
ken
la source
2
Cela fonctionne, mais élimine les avantages de la notation littérale de l'objet.
kpozin
Certes, désolé d'avoir manqué la balise littérale objet à l'origine. J'utilise principalement des littéraux d'objet uniquement pour les structures de données, et chaque fois que je veux une logique supplémentaire (qui pourrait ressembler à une classe), je crée l'objet comme le résultat d'une fonction pour cette raison.
Ken
6

juste pour la réflexion - placez les propriétés de l'objet hors d'une chronologie:

var foo = {
    a: function(){return 5}(),
    b: function(){return 6}(),
    c: function(){return this.a + this.b}
}

console.log(foo.c())

il y a aussi de meilleures réponses ci-dessus . C'est ainsi que j'ai modifié l'exemple de code avec lequel vous vous êtes interrogé.

MISE À JOUR:

var foo = {
    get a(){return 5},
    get b(){return 6},
    get c(){return this.a + this.b}
}
// console.log(foo.c);
animaacija
la source
2
Dans ES6, vous pouvez rendre cette approche générale beaucoup plus élégante: var foo = { get a(){return 5}, get b(){return 6}, get c(){return this.a + this.b} }alors maintenant vous pouvez simplement faire à la foo.cplace de foo.c():) (N'hésitez pas à coller cela dans votre réponse pour que le formatage soit meilleur!)
5

Créer une nouvelle fonction sur votre objet littéral et invoquer un constructeur semble un changement radical par rapport au problème d'origine, et ce n'est pas nécessaire.

Vous ne pouvez pas référencer une propriété frère pendant l'initialisation littérale de l'objet.

var x = { a: 1, b: 2, c: a + b } // not defined 
var y = { a: 1, b: 2, c: y.a + y.b } // not defined 

La solution la plus simple pour les propriétés calculées suit (pas de tas, pas de fonctions, pas de constructeur):

var x = { a: 1, b: 2 };

x.c = x.a + x.b; // apply computed property
Rick O'Shea
la source
3

Les autres réponses publiées ici sont meilleures, mais voici une alternative qui:

  • Définit la valeur à l'initialisation (pas un getter, ni un dérivé, etc.)
  • Ne nécessite aucun type de init() ou code en dehors du littéral objet
  • Est un littéral d'objet et non une fonction d'usine ou un autre mécanisme de création d'objets.
  • Ne devrait pas avoir d'impact sur les performances (sauf à l'initialisation)

Fonctions anonymes auto-exécutables et stockage de fenêtres

var foo = {
    bar:(function(){
        window.temp = "qwert";
        return window.temp;
    })(),
    baz: window.temp
};

La commande est garantie ( baravantbaz ).

Cela pollue windowbien sûr, mais je ne peux pas imaginer que quelqu'un écrive un script qui nécessite window.tempd'être persistant. Peut êtretempMyApp - si vous êtes paranoïaque.

C'est aussi moche mais parfois utile. Par exemple, lorsque vous utilisez une API avec des conditions d'initialisation rigides et que vous n'avez pas envie de refactoriser la portée est correcte.

Et c'est sec, bien sûr.

DanielST
la source
3

La clé de tout cela est SCOPE .

Vous devez encapsuler le "parent" (objet parent) de la propriété que vous souhaitez définir comme son propre objet instancié, puis vous pouvez faire des références aux propriétés frères en utilisant le mot clé this

Il est très, très important de se rappeler que si vous vous référez thissans le faire au préalable, thisvous ferez référence à la portée extérieure ... qui sera l' windowobjet.

var x = 9   //this is really window.x
var bar = {
  x: 1,
  y: 2,
  foo: new function(){
    this.a = 5, //assign value
    this.b = 6,
    this.c = this.a + this.b;  // 11
  },
  z: this.x   // 9 (not 1 as you might expect, b/c *this* refers `window` object)
};
Communauté
la source
2
Ce n'est même pas un JS valide.
2

si votre objet est écrit comme une fonction qui renvoie un objet ET que vous utilisez des 'méthodes' d'attribut d'objet ES6, alors il est possible:

const module = (state) => ({
  a: 1,
  oneThing() {
    state.b = state.b + this.a
  },
  anotherThing() {
    this.oneThing();
    state.c = state.b + this.a
  },
});

const store = {b: 10};
const root = module(store);

root.oneThing();
console.log(store);

root.anotherThing();
console.log(store);

console.log(root, Object.keys(root), root.prototype);
daviestar
la source
2

J'utilise le code suivant comme alternative, et cela fonctionne. Et la variable peut aussi être un tableau. (@ Fausto R.)

var foo = {
  a: 5,
  b: 6,
  c: function() {
    return this.a + this.b;
  },

  d: [10,20,30],
  e: function(x) {
    this.d.push(x);
    return this.d;
  }
};
foo.c(); // 11
foo.e(40); // foo.d = [10,20,30,40]
Indiana
la source
2

Voici une méthode ES6 soignée:

var foo = (o => ({
    ...o,
    c: o.a + o.b
  }))({
    a: 5,
    b: 6
  });
  
console.log(foo);

Je l'utilise pour faire quelque chose comme ça:

const constants = Object.freeze(
  (_ => ({
    ..._,
    flag_data: {
      [_.a_flag]: 'foo',
      [_.b_flag]: 'bar',
      [_.c_flag]: 'oof'
    }
  }))({
    a_flag: 5,
    b_flag: 6,
    c_flag: 7,
  })
);

console.log(constants.flag_data[constants.b_flag]);

UDrake
la source
1

Que diriez-vous de cette solution, cela fonctionnera également avec les objets imbriqués avec tableau

      Object.prototype.assignOwnProVal
     = function (to,from){ 
            function compose(obj,string){ 
                var parts = string.split('.'); 
                var newObj = obj[parts[0]]; 
                if(parts[1]){ 
                    parts.splice(0,1);
                    var newString = parts.join('.'); 
                    return compose(newObj,newString); 
                } 
                return newObj; 
            } 
            this[to] = compose(this,from);
     } 
     var obj = { name : 'Gaurav', temp : 
                  {id : [10,20], city:
                        {street:'Brunswick'}} } 
     obj.assignOwnProVal('street','temp.city.street'); 
     obj.assignOwnProVal('myid','temp.id.1');
Gaurav
la source
0

Ajout d'une option car je n'ai pas vu ce scénario exact couvert. Si vous ne voulez pasc mettre à jour quand aou bmettre à jour, alors un ES6 IIFE fonctionne bien.

var foo = ((a,b) => ({
    a,
    b,
    c: a + b
}))(a,b);

Pour mes besoins, j'ai un objet qui se rapporte à un tableau qui finira par être utilisé dans une boucle, donc je ne veux calculer une configuration commune qu'une seule fois, alors voici ce que j'ai:

  let processingState = ((indexOfSelectedTier) => ({
      selectedTier,
      indexOfSelectedTier,
      hasUpperTierSelection: tiers.slice(0,indexOfSelectedTier)
                             .some(t => pendingSelectedFiltersState[t.name]),
  }))(tiers.indexOf(selectedTier));

Étant donné que je dois définir une propriété pour indexOfSelectedTieret que je dois utiliser cette valeur lors de la définition de la hasUpperTierSelectionpropriété, je calcule d'abord cette valeur et la transmets en tant que paramètre à l'IIFE

Snekse
la source
0

Une autre approche serait de déclarer l'objet avant de lui affecter des propriétés:

const foo = {};
foo.a = 5;
foo.b = 6;
foo.c = foo.a + foo.b;  // Does work
foo.getSum = () => foo.a + foo.b + foo.c;  // foo.getSum() === 22

Avec cela, vous pouvez utiliser le nom de variable d'objet pour accéder aux valeurs déjà attribuées.
Idéal pour le config.jsfichier.

5ervant
la source
Ce n'est pas une auto-référence, mais plutôt une référence à la variable déclarée fooqui pointe vers l'objet en question.
Derek Henderson
0
var x = {
    a: (window.secreta = 5),
    b: (window.secretb = 6),
    c: window.secreta + window.secretb
};

C'est presque identique à la réponse de @ slicedtoad, mais n'utilise pas de fonction.

David Newberry
la source
-1

Remarque: Cette solution utilise Typescript (vous pouvez utiliser le JS vanilla que TS compile si nécessaire)

class asd {
    def = new class {
        ads= 'asd';
        qwe= this.ads + '123';
    };

    // this method is just to check/test this solution 
    check(){
        console.log(this.def.qwe);
    }
}

// these two lines are just to check
let instance = new asd();
instance.check();

Ici, nous utilisions des expressions de classe pour obtenir l'interface littérale d'objet imbriqué que nous souhaiterions. C'est la deuxième meilleure chose à mon humble avis de pouvoir référencer les propriétés d'un objet lors de la création.

La chose principale à noter est qu'en utilisant cette solution, vous avez exactement la même interface que vous auriez eue avec un objet littéral. Et la syntaxe est assez proche d'un littéral objet lui-même (par rapport à l'utilisation d'une fonction, etc.).

Comparez les éléments suivants

Solution que j'ai proposée

class asd {
    def = new class {
        ads= 'asd';
        qwe= this.ads + '123';
    };

Solution si les littéraux d'objet auraient suffi

var asd = {
    def : {
        ads:'asd',
        qwe: this.ads + '123';, //ILLEGAL CODE; just to show ideal scenario
    }
}

Un autre exemple

Ici, dans cette classe, vous pouvez combiner plusieurs chemins relatifs entre eux, ce qui n'est pas possible avec un objet littéral.

class CONSTANT {
    static readonly PATH = new class {
        /** private visibility because these relative paths don't make sense for direct access, they're only useful to path class
         *
         */
        private readonly RELATIVE = new class {
            readonly AFTER_EFFECTS_TEMPLATE_BINARY_VERSION: fs.PathLike = '\\assets\\aep-template\\src\\video-template.aep';
            readonly AFTER_EFFECTS_TEMPLATE_XML_VERSION: fs.PathLike = '\\assets\\aep-template\\intermediates\\video-template.aepx';
            readonly RELATIVE_PATH_TO_AFTER_EFFECTS: fs.PathLike = '\\Adobe\\Adobe After Effects CC 2018\\Support Files\\AfterFX.exe';
            readonly OUTPUT_DIRECTORY_NAME: fs.PathLike = '\\output';
            readonly INPUT_DIRECTORY_NAME: fs.PathLike = '\\input';
            readonly ASSETS_DIRECTORY_NAME: fs.PathLike = '\\assets';
        };
    }
}
Dheeraj Bhaskar
la source
2
Serait-ce parce que votre réponse est totalement hors de propos? Je suis d'accord que les downvoters devraient expliquer, mais votre réponse claire n'a rien à voir avec la question…
Manngo
@Manngo merci de l'avoir signalé. Honnêtement, je poserais la même question que OP et j'utilise la solution que j'ai suggérée. Je ne sais pas pourquoi cela est considéré comme non pertinent. Si vous avez le temps, veuillez expliquer afin que je puisse améliorer la réponse ou au moins savoir où je me trompe. Je ne comprends malheureusement pas pourquoi ce n'est pas une solution raisonnable.
Dheeraj Bhaskar
-2

Si vous souhaitez utiliser JS natif, les autres réponses fournissent de bonnes solutions.

Mais si vous êtes prêt à écrire des objets auto-référencés comme:

{ 
  a: ...,
  b: "${this.a + this.a}",
}

J'ai écrit une bibliothèque npm appelée self-referenced-object qui prend en charge cette syntaxe et renvoie un objet natif.

alex-e-leon
la source
1
Veuillez éviter les réponses contenant uniquement des liens . Les réponses qui sont "à peine plus qu'un lien vers un site externe" peuvent être supprimées .
Quentin
@Quentin avez-vous des suggestions pour améliorer ma réponse? Les autres réponses à cette question couvrent comment vous pourriez être en mesure d'écrire des objets auto-référencés en javascript natif, mais si vous voulez écrire des objets auto-référencés avec une syntaxe similaire à la syntaxe de la question originale des affiches, je pense que la bibliothèque qui J'ai écrit peut être utile à ceux qui recherchent une solution. Heureux d'avoir des commentaires.
alex-e-leon
Quelques choses à améliorer ici. Tout d'abord, et le plus évidemment, vous utilisez la syntaxe littérale du modèle sans tiques inverses. Votre bvaleur de la propriété doit être: ${this.a + this.a}. Deuxièmement, mais moins important, vous voudriez retourner un nombre, pas une chaîne en utilisant quelque chose comme parseInt. Enfin et surtout, lorsque j'ai essayé cet exemple, cela ne fonctionne tout simplement pas, pour la même raison que l'OP le demande. Le thisretourne undefined lorsqu'il est utilisé sa propre déclaration d'objet. @ alex-e-leon
Alec Donald Mather
@AlecDonaldMather - merci d'avoir pris le temps de jeter un coup d'œil et de nous faire part de vos commentaires! Si le projet vous intéresse, il serait préférable de déplacer cette discussion sur github, mais pour répondre à certains de vos commentaires: - Utilisation de backticks: Comme mentionné dans les commentaires précédents, cette syntaxe n'est pas prise en charge par JS, et donc utilisez des chaînes à la place de backticks est nécessaire ici pour éviter que js essaie de résoudre "ceci" avant que l'obj ne soit défini - renvoyer un nombre, cela devrait fonctionner si a + b sont déjà des nombres, car a + b retournera un nombre si a et b sont tous les deux déjà des nombres.
alex-e-leon
Pour ce retour indéfini, pouvez-vous expliquer comment vous avez essayé d'utiliser la bibliothèque? Cela ne devrait pas arriver, mais il y a peut-être un cas de bord que j'ai laissé de côté? Cela dit, cette bibliothèque ne résout pas complètement le problème et possède son propre ensemble de compromis, mais si vous êtes intéressé à m'aider à l'améliorer / à l'utiliser, faites-le moi savoir!
alex-e-leon