Quelles techniques peuvent être utilisées pour définir une classe en JavaScript et quels sont leurs compromis?

686

Je préfère utiliser la POO dans des projets à grande échelle comme celui sur lequel je travaille en ce moment. J'ai besoin de créer plusieurs classes en JavaScript mais, si je ne me trompe pas, il y a au moins deux façons de procéder. Quelle serait la syntaxe et pourquoi cela se ferait-il de cette façon?

Je voudrais éviter d'utiliser des bibliothèques tierces - du moins au début.
À la recherche d'autres réponses, j'ai trouvé l'article Programmation orientée objet avec JavaScript, Partie I: Héritage - Doc JavaScript qui traite de la programmation orientée objet en JavaScript. Existe-t-il une meilleure façon de faire l'héritage?

Karim
la source
note: il s'agit d'un doublon de stackoverflow.com/questions/355848
Jason S
3
Personnellement, j'aime déclarer des membres de classe dans le corps de la fonction. J'utilise la technique de «fixation du ceci» pour créer une fermeture afin qu'elle se comporte plus comme une classe. J'ai un exemple détaillé sur mon blog: ncombo.wordpress.com/2012/12/30/…
Jon
J'ai porté la plupart des fonctionnalités C ++ OOP sur JavaScript avec une syntaxe simple et naturelle. Voir ma réponse ici: stackoverflow.com/a/18239463/1115652
Il n'y a pas de classes en JavaScript. Mais si vous souhaitez simuler un comportement de classe similaire dans JS, vous le pouvez. Voir les détails dans: symfony-world.blogspot.com/2013/10/…
ducin

Réponses:

743

Voici la façon de le faire sans utiliser de bibliothèques externes:

// Define a class like this
function Person(name, gender){

   // Add object properties like this
   this.name = name;
   this.gender = gender;
}

// Add methods like this.  All Person objects will be able to invoke this
Person.prototype.speak = function(){
    alert("Howdy, my name is" + this.name);
};

// Instantiate new objects with 'new'
var person = new Person("Bob", "M");

// Invoke methods like this
person.speak(); // alerts "Howdy, my name is Bob"

Maintenant, la vraie réponse est beaucoup plus complexe que cela. Par exemple, il n'y a pas de classes en JavaScript. JavaScript utilise un prototypeschéma d'héritage basé sur.

De plus, il existe de nombreuses bibliothèques JavaScript populaires qui ont leur propre style d'approximation des fonctionnalités de classe en JavaScript. Vous voudrez vérifier au moins Prototype et jQuery .

Décider lequel d'entre eux est le "meilleur" est un excellent moyen de commencer une guerre sainte sur Stack Overflow. Si vous vous lancez dans un projet plus volumineux, il vaut vraiment la peine d'apprendre une bibliothèque populaire et de le faire à sa manière. Je suis un type Prototype, mais Stack Overflow semble pencher vers jQuery.

Dans la mesure où il n'y a qu'une "façon de le faire", sans aucune dépendance vis-à-vis des bibliothèques externes, la façon dont j'ai écrit est à peu près la même.

Triptyque
la source
48
Mais cela ne fonctionne pas comme le langage X où j'ai appris la seule vraie façon dont un objet utilisé pour créer des instances d'objet devrait fonctionner :(
Erik Reppen
2
Selon developer.mozilla.org/en-US/docs/Web/JavaScript/… les propriétés devraient également être ajoutées au prototype ("Person.prototype.name = '';")
DaveD
1
@DaveD - peut-être que oui, mais ne semble plus ..?
Kieren Johnstone
6
jQuery ne fournit même aucun moyen de créer des fonctionnalités de classe ??? (Toutes les classes qu'il a sont des classes CSS) Vous devez le supprimer de cette partie de la réponse.
Bergi
7
Depuis la seconde moitié de 2015, EcmaScript 6 a publié un nouveau standard, donc je propose de le faire de la nouvelle façon (beaucoup plus propre et plus simple
DevWL
213

La meilleure façon de définir une classe en JavaScript est de ne pas définir de classe.

Sérieusement.

Il existe plusieurs variantes de l'orientation objet, dont certaines sont:

  • OO basé sur une classe (introduit pour la première fois par Smalltalk)
  • OO basé sur un prototype (introduit pour la première fois par Self)
  • OO multiméthodes (présenté pour la première fois par CommonLoops, je pense)
  • OO basé sur un prédicat (aucune idée)

Et probablement d'autres que je ne connais pas.

JavaScript implémente OO basé sur un prototype. Dans OO basé sur un prototype, de nouveaux objets sont créés en copiant d'autres objets (au lieu d'être instanciés à partir d'un modèle de classe) et les méthodes vivent directement dans les objets plutôt que dans les classes. L'héritage se fait par délégation: si un objet n'a pas de méthode ou de propriété, il est recherché sur son ou ses prototypes (c'est-à-dire l'objet à partir duquel il a été cloné), puis sur les prototypes du prototype et ainsi de suite.

En d'autres termes: il n'y a pas de classes.

JavaScript a en fait une belle modification de ce modèle: les constructeurs. Non seulement vous pouvez créer des objets en copiant ceux qui existent déjà, mais vous pouvez aussi les construire "à partir de rien", pour ainsi dire. Si vous appelez une fonction avec le newmot - clé, cette fonction devient un constructeur et le thismot - clé ne pointera pas vers l'objet actuel mais vers un objet "vide" nouvellement créé. Ainsi, vous pouvez configurer un objet comme vous le souhaitez. De cette façon, les constructeurs JavaScript peuvent assumer l'un des rôles des classes dans les OO classiques basés sur les classes: servir de modèle ou de modèle pour de nouveaux objets.

Maintenant, JavaScript est un langage très puissant, il est donc assez facile d'implémenter un système OO basé sur des classes dans JavaScript si vous le souhaitez. Cependant, vous ne devriez le faire que si vous en avez vraiment besoin et pas seulement parce que c'est ainsi que Java le fait.

Jörg W Mittag
la source
Msgstr "Si vous appelez une fonction avec le nouveau mot - clé, cette fonction devient un constructeur et le mot - clé this ne pointera pas vers l 'objet actuel mais vers un" vide "nouvellement créé". Si vous appelez une fonction sans le nouveau mot-clé, cela fera référence au contexte d'appel, par défaut l'objet global (fenêtre). En mode strict, undefined est la valeur par défaut. call, apply and bind prend le contexte d'appel comme premier paramètre. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Elias Hasle
83

Classes ES2015

Dans la spécification ES2015, vous pouvez utiliser la syntaxe de classe qui est juste du sucre sur le système prototype.

class Person {
  constructor(name) {
    this.name = name;
  }
  toString() {
    return `My name is ${ this.name }.`;
  }
}

class Employee extends Person {
  constructor(name, hours) {
    super(name);
    this.hours = hours;
  }
  toString() {
    return `${ super.toString() } I work ${ this.hours } hours.`;
  }
}

Avantages

Le principal avantage est que les outils d'analyse statique trouvent plus facile de cibler cette syntaxe. Il est également plus facile pour d'autres venant de langues basées sur les classes d'utiliser la langue comme polyglotte.

Avertissements

Méfiez-vous de ses limites actuelles. Pour obtenir des propriétés privées, il faut recourir à l' utilisation de symboles ou de WeakMaps . Dans les versions futures, les classes seront très probablement étendues pour inclure ces fonctionnalités manquantes.

Soutien

Le support du navigateur n'est pas très bon pour le moment (pris en charge par presque tout le monde sauf IE), mais vous pouvez utiliser ces fonctionnalités maintenant avec un transpilateur comme Babel .

Ressources

Vallée
la source
56

Je préfère utiliser celui de Daniel X. Moore {SUPER: SYSTEM}. Il s'agit d'une discipline qui offre des avantages tels que les vraies variables d'instance, l'héritage basé sur les traits, les hiérarchies de classes et les options de configuration. L'exemple ci-dessous illustre l'utilisation de vraies variables d'instance, ce qui, selon moi, est le plus grand avantage. Si vous n'avez pas besoin de variables d'instance et êtes satisfait uniquement des variables publiques ou privées, il existe probablement des systèmes plus simples.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  return {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };
}

var fogel = Person({
  age: "old enough"
});
fogel.introduce(); // "Hi I'm McLovin and I'm old enough"

Wow, ce n'est pas vraiment très utile en soi, mais jetez un œil à l'ajout d'une sous-classe:

function Ninja(I) {
  I = I || {};

  Object.reverseMerge(I, {
    belt: "black"
  });

  // Ninja is a subclass of person
  return Object.extend(Person(I), {
    greetChallenger: function() {
      return "In all my " + I.age + " years as a ninja, I've never met a challenger as worthy as you...";
    }
  });
}

var resig = Ninja({name: "John Resig"});

resig.introduce(); // "Hi I'm John Resig and I'm 25"

Un autre avantage est la possibilité d'avoir des modules et un héritage basé sur les traits.

// The Bindable module
function Bindable() {

  var eventCallbacks = {};

  return {
    bind: function(event, callback) {
      eventCallbacks[event] = eventCallbacks[event] || [];

      eventCallbacks[event].push(callback);
    },

    trigger: function(event) {
      var callbacks = eventCallbacks[event];

      if(callbacks && callbacks.length) {
        var self = this;
        callbacks.forEach(function(callback) {
          callback(self);
        });
      }
    },
  };
}

Un exemple de la classe person inclut le module bindable.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  var self = {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };

  // Including the Bindable module
  Object.extend(self, Bindable());

  return self;
}

var person = Person();
person.bind("eat", function() {
  alert(person.introduce() + " and I'm eating!");
});

person.trigger("eat"); // Blasts the alert!

Divulgation: je suis Daniel X. Moore et voici mon {SUPER: SYSTEM}. C'est le meilleur moyen de définir une classe en JavaScript.

Daniel X Moore
la source
@DanielXMoore "Les variables d'instance sont partagées entre les instances individuelles d'une classe" Ce ne sont pas des variables d'instance, ce sont des variables statiques / de classe.
JAB
2
@JAB C'est incorrect, les variables statiques / classe sont partagées entre toutes les instances d'une classe. Chaque instance a ses propres variables d'instance.
Daniel X Moore
(Autrement dit, en utilisant le sens normal du terme "variable d'instance", le fait qu'une variable soit ou non une est orthogonale au niveau d'accessibilité de la variable.)
JAB
2
Vous ressembliez presque à un super-héros pour avoir réclamé le meilleur xD
Dadan
Une approche simple pour définir une classe Javascript à l'aide d'objets javascript: wapgee.com/story/i/203
Ilyas karim
41
var Animal = function(options) {
    var name = options.name;
    var animal = {};

    animal.getName = function() {
        return name;
    };

    var somePrivateMethod = function() {

    };

    return animal;
};

// usage
var cat = Animal({name: 'tiger'});
liammclennan
la source
C'est une manière très élégante de construire une structure d'objet utilisable sans avoir à importer quoi que ce soit. J'utilisais le système de classe de Resig, mais j'aime peut-être mieux cela. Je vous remercie.
Tim Scollick du
29
Le problème avec cette approche est que chaque fois que vous créez une nouvelle instance Animal, cela va redéfinir les fonctions plutôt que de les définir une seule fois avec prototype.
Justin
33

Voici les façons de créer des objets en javascript, que j'ai utilisé jusqu'à présent

Exemple 1:

obj = new Object();
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}

Exemple 2:

obj = {};
obj.name = 'test';
obj.sayHello = function() {
    console.log('Hello '+ this.name);
}
obj.sayHello();

Exemple 3:

var obj = function(nameParam) {
    this.name = nameParam;
}
obj.prototype.sayHello = function() {
    console.log('Hello '+ this.name);
}

Exemple 4: Avantages réels d'Object.create (). veuillez consulter [ce lien]

var Obj = {
    init: function(nameParam) {
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var usrObj = Object.create(Obj);  // <== one level of inheritance

usrObj.init('Bob');
usrObj.sayHello();

Exemple 5 (Object.create de Crockford personnalisé):

Object.build = function(o) {
   var initArgs = Array.prototype.slice.call(arguments,1)
   function F() {
      if((typeof o.init === 'function') && initArgs.length) {
         o.init.apply(this,initArgs)
      }
   }
   F.prototype = o
   return new F()
}
MY_GLOBAL = {i: 1, nextId: function(){return this.i++}}  // For example

var userB = {
    init: function(nameParam) {
        this.id = MY_GLOBAL.nextId();
        this.name = nameParam;
    },
    sayHello: function() {
        console.log('Hello '+ this.name);
    }
};
var bob = Object.build(userB, 'Bob');  // Different from your code
bob.sayHello();


Pour garder la réponse à jour avec ES6 / ES2015

Une classe est définie comme ceci:

class Person {
    constructor(strName, numAge) {
        this.name = strName;
        this.age = numAge;
    }

    toString() {
        return '((Class::Person) named ' + this.name + ' & of age ' + this.age + ')';
    }
}

let objPerson = new Person("Bob",33);
console.log(objPerson.toString());
Amol M Kulkarni
la source
1
@Justin: Veuillez me faire savoir ce qui n'est pas valide?
Amol M Kulkarni
En étudiant ces notations, je suis également tombé sur ce set (). Par exemple: this.set ('port', 3000). Je suppose que cela est utilisé pour définir la propriété de port de l'objet. Si oui, pourquoi n'utilisons-nous pas directement: {port: 3000}. Y a-t-il une documentation où je peux obtenir plus de détails.
adityah
24

Je pense que vous devriez lire l' héritage prototypique de Douglas Crockford en JavaScript et l'héritage classique en JavaScript .

Exemples de sa page:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

Effet? Il vous permettra d'ajouter des méthodes de manière plus élégante:

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.method('setValue', function (value) {
    this.value = value;
    return this;
});

Je recommande également ses vidéos: JavaScript avancé .

Vous pouvez trouver plus de vidéos sur sa page: http://javascript.crockford.com/ Dans le livre de John Reisig, vous pouvez trouver de nombreux exemples sur le site Web de Douglas Crockfor.

Jarek
la source
25
Est ce juste moi? Comment diable est-ce plus élégant? J'appellerais 'strings'beaucoup de choses des définitions de fonctions avec des noms réels , mais l'élégance n'en fait pas partie ...
fgysin réintègre Monica
4
@JAB, mais la réflexion est l'exception, pas la règle. Avec la méthode ci-dessus, vous devez déclarer toutes vos méthodes avec des chaînes.
Kirk Woll
16

Parce que je n'admettrai pas le plan d'usine YUI / Crockford et parce que j'aime garder les choses autonomes et extensibles, c'est ma variation:

function Person(params)
{
  this.name = params.name || defaultnamevalue;
  this.role = params.role || defaultrolevalue;

  if(typeof(this.speak)=='undefined') //guarantees one time prototyping
  {
    Person.prototype.speak = function() {/* do whatever */};
  }
}

var Robert = new Person({name:'Bob'});

où idéalement le test typeof est sur quelque chose comme la première méthode prototypée

annakata
la source
Je l'aime. J'utilise le plus souvent la syntaxe standard de JS car je n'aime pas l'idée de copier des fonctions dans chaque instance d'objet. Cependant, j'ai toujours manqué la beauté de la solution autonome, et cela la résout assez bien.
Lukasz Korzybski
1
Pas sûr mais j'ai compris que la définition de la fonction prototype à l'intérieur de la portée (un peu comme une fermeture) d'une fonction entraîne une fuite de mémoire car le garbage collector ne peut pas y arriver dans l'instance de ces classes.
Sanne
15

Si vous optez pour la simplicité, vous pouvez éviter complètement le "nouveau" mot clé et utiliser simplement des méthodes d'usine. Je préfère cela parfois, car j'aime utiliser JSON pour créer des objets.

function getSomeObj(var1, var2){
  var obj = {
     instancevar1: var1,
     instancevar2: var2,
     someMethod: function(param)
     {  
          //stuff; 
     }
  };
  return obj;
}

var myobj = getSomeObj("var1", "var2");
myobj.someMethod("bla");

Cependant, je ne sais pas quel est le niveau de performance pour les gros objets.

Sam
la source
La ligne obj.instancevar1 = var1 n'est pas nécessaire, car l'objet interne aura accès aux paramètres de getSomeObj ().
Triptyque
Sensationnel. Cela me fait mal au cerveau mais il y a une certaine élégance. Donc la partie "obj.instancevar1 = var1" est le début d'une sorte de constructeur, je suppose?
Karim
Je viens de voir le commentaire de Triptyque. Je vois. Ainsi, vous pouvez simplement faire quelque chose comme "instancevar1: var1" où l'objet interne est instancié.
Karim
Exactement ... lorsque vous utilisez {} pour définir un objet, il a accès aux variables qui sont actuellement dans la portée.
Sam
10
Avec cette approche, vous perdez la capacité d'hériter, et puisque vous n'utilisez pas obj.prototype.something, vous définissez les fonctions chaque fois que vous utilisez l'objet = plus de mémoire et plus lentement.
certains
12
var Student = (function () {
    function Student(firstname, lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
        this.fullname = firstname + " " + lastname;
    }

    Student.prototype.sayMyName = function () {
        return this.fullname;
    };

    return Student;
}());

var user = new Student("Jane", "User");
var user_fullname = user.sayMyName();

C'est la façon dont TypeScript compile la classe avec le constructeur en JavaScript.

Mick
la source
10

La manière la plus simple est:

function Foo(a) {
  var that=this;

  function privateMethod() { .. }

  // public methods
  that.add = function(b) {
    return a + b;
  };
  that.avg = function(b) {
    return that.add(b) / 2; // calling another public method
  };
}

var x = new Foo(10);
alert(x.add(2)); // 12
alert(x.avg(20)); // 15

La raison en thatest que cela thispeut être lié à autre chose si vous donnez une méthode en tant que gestionnaire d'événements, vous enregistrez donc la valeur pendant l'instanciation et l'utilisez plus tard.

Edit: ce n'est certainement pas le meilleur moyen, juste un moyen simple. J'attends aussi de bonnes réponses!

orip
la source
1
La construction that = this n'est pas nécessaire ici. De plus, les méthodes add () et avg () seront copiées pour chaque "instance" de la classe Foo, plutôt que partagées entre elles.
Triptyque
1
Est-ce nécessaire (sorta) dans ce cas, mais pas le cas simple que vous avez fourni.
Triptyque
9

Vous souhaitez probablement créer un type à l'aide du modèle de pliage:

    // Here is the constructor section.
    var myType = function () {
        var N = {}, // Enclosed (private) members are here.
            X = this; // Exposed (public) members are here.

        (function ENCLOSED_FIELDS() {
            N.toggle = false;
            N.text = '';
        }());

        (function EXPOSED_FIELDS() {
            X.count = 0;
            X.numbers = [1, 2, 3];
        }());

        // The properties below have access to the enclosed fields.
        // Careful with functions exposed within the closure of the
        // constructor, each new instance will have it's own copy.
        (function EXPOSED_PROPERTIES_WITHIN_CONSTRUCTOR() {
            Object.defineProperty(X, 'toggle', {
                get: function () {
                    var before = N.toggle;
                    N.toggle = !N.toggle;
                    return before;
                }
            });

            Object.defineProperty(X, 'text', {
                get: function () {
                    return N.text;
                },
                set: function (value) {
                    N.text = value;
                }
            });
        }());
    };

    // Here is the prototype section.
    (function PROTOTYPE() {
        var P = myType.prototype;

        (function EXPOSED_PROPERTIES_WITHIN_PROTOTYPE() {
            Object.defineProperty(P, 'numberLength', {
                get: function () {
                    return this.numbers.length;
                }
            });
        }());

        (function EXPOSED_METHODS() {
            P.incrementNumbersByCount = function () {
                var i;
                for (i = 0; i < this.numbers.length; i++) {
                    this.numbers[i] += this.count;
                }
            };
            P.tweak = function () {
                if (this.toggle) {
                    this.count++;
                }
                this.text = 'tweaked';
            };
        }());
    }());

Ce code vous donnera un type appelé myType . Il aura des champs privés internes appelés bascule et texte . Il aura également ces membres exposés: les champs comptent et nombre ; les propriétés bascule , text et numberLength ; les méthodes incrementNumbersByCount et tweak .

Le modèle de pliage est détaillé ici: Modèle de pliage Javascript

intrepidis
la source
3

Code golf pour la réponse de @ liammclennan .

var Animal = function (args) {
  return {
    name: args.name,

    getName: function () {
      return this.name; // member access
    },

    callGetName: function () {
      return this.getName(); // method call
    }
  };
};

var cat = Animal({ name: 'tiger' });
console.log(cat.callGetName());

tponthieux
la source
2

MooTools (My Object Oriented Tools) est centré sur l'idée de classes . Vous pouvez même étendre et implémenter avec héritage.

Une fois maîtrisé, il permet un javascript puissant et ridiculement réutilisable.

Ryan Florence
la source
2

Classes basées sur des objets avec héritage

var baseObject = 
{
     // Replication / Constructor function
     new : function(){
         return Object.create(this);   
     },

    aProperty : null,
    aMethod : function(param){
      alert("Heres your " + param + "!");
    },
}


newObject = baseObject.new();
newObject.aProperty = "Hello";

anotherObject = Object.create(baseObject); 
anotherObject.aProperty = "There";

console.log(newObject.aProperty) // "Hello"
console.log(anotherObject.aProperty) // "There"
console.log(baseObject.aProperty) // null

Simple, doux et fait tout.

Ulad Kasach
la source
1

Une base

function Base(kind) {
    this.kind = kind;
}

Une classe

// Shared var
var _greeting;

(function _init() {
    Class.prototype = new Base();
    Class.prototype.constructor = Class;
    Class.prototype.log = function() { _log.apply(this, arguments); }
    _greeting = "Good afternoon!";
})();

function Class(name, kind) {
    Base.call(this, kind);
    this.name = name;
}

// Shared function
function _log() {
    console.log(_greeting + " Me name is " + this.name + " and I'm a " + this.kind);
}

action

var c = new Class("Joe", "Object");
c.log(); // "Good afternoon! Me name is Joe and I'm a Object"
Mikael Dúi Bolinder
la source
1

Sur la base de l'exemple de Triptyque, cela pourrait même être plus simple:

    // Define a class and instantiate it
    var ThePerson = new function Person(name, gender) {
        // Add class data members
        this.name = name;
        this.gender = gender;
        // Add class methods
        this.hello = function () { alert('Hello, this is ' + this.name); }
    }("Bob", "M"); // this instantiates the 'new' object

    // Use the object
    ThePerson.hello(); // alerts "Hello, this is Bob"

Cela ne crée qu'une seule instance d'objet, mais est toujours utile si vous souhaitez encapsuler un tas de noms de variable et de méthodes dans une classe. Normalement, il n'y aurait pas les arguments "Bob, M" au constructeur, par exemple si les méthodes étaient des appels à un système avec ses propres données, comme une base de données ou un réseau.

Je suis encore trop nouveau avec JS pour voir pourquoi cela n'utilise pas la prototypechose.

Roland
la source
0

JavaScript est orienté objet , mais il est radicalement différent des autres langages OOP comme Java, C # ou C ++. N'essayez pas de le comprendre comme ça. Jetez cette vieille connaissance et recommencez. JavaScript a besoin d'une réflexion différente.

Je suggère d'obtenir un bon manuel ou quelque chose sur le sujet. J'ai moi-même trouvé les tutoriels ExtJS les meilleurs pour moi, même si je n'ai pas utilisé le framework avant ou après l'avoir lu. Mais cela donne une bonne explication de ce qui se passe dans le monde JavaScript. Désolé, il semble que ce contenu ait été supprimé. Voici un lien vers la copie archive.org à la place. Fonctionne aujourd'hui. : P

Vilx-
la source
2
Orienté objet? Je pensais que c'était fonctionnel .
Peter Mortensen
Le lien "ExtJS Tutorials" est rompu.
Peter Mortensen
Je pense qu'il serait plus explicatif d'expliquer que les fonctions en javascript sont des objets, et les règles de portée entre crochets de javascript rendent chaque bloc de fonction encapsulant.
mibbit
-1

//new way using this and new
function Persons(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

var gee=new Persons("gee");
gee.greeting();

var gray=new Persons("gray");
gray.greeting();

//old way
function createPerson(name){
 var obj={};
 obj.name=name;
 obj.greeting = function(){
 console.log("hello I am"+obj.name);
 }; 
  return obj;
}

var gita=createPerson('Gita');
gita.greeting();

Avinash Maurya
la source