Question Quel est le nouveau mot clé en JavaScript?


le new Le mot clé en JavaScript peut être assez déroutant quand il est rencontré pour la première fois, car les gens ont tendance à penser que JavaScript n'est pas un langage de programmation orienté objet.

  • Qu'Est-ce que c'est?
  • Quels problèmes résout-il?
  • Quand est-ce approprié et quand non?

1555
2017-10-29 21:32


origine


Réponses:


Il fait 5 choses:

  1. Il crée un nouvel objet. Le type de cet objet est simplement objet.
  2. Il définit interne de ce nouvel objet, inaccessible, [[prototype]] (c'est à dire. __proto__) propriété à être la fonction du constructeur externe, accessible, prototype objet (chaque objet de fonction a automatiquement un prototype propriété).
  3. Cela fait le this point variable vers l'objet nouvellement créé.
  4. Il exécute la fonction constructeur, en utilisant l'objet nouvellement créé chaque fois this est mentionné.
  5. Il renvoie l'objet nouvellement créé, sauf si la fonction constructeur renvoie unnull référence d'objet. Dans ce cas, cette référence d'objet est renvoyée à la place.

Remarque: fonction constructeur renvoie la fonction après le new mot-clé, comme dans

new ConstructorFunction(arg1, arg2)

Une fois ceci fait, si une propriété non définie du nouvel objet est demandée, le script vérifie la propriété de l'objet. [[prototype]] objet pour la propriété à la place. C'est ainsi que vous pouvez obtenir quelque chose de similaire à l'héritage de classe traditionnel en JavaScript.

La partie la plus difficile à ce sujet est le point numéro 2. Chaque objet (y compris les fonctions) a cette propriété interne appelée [[prototype]]. Ça peut seulement être défini au moment de la création de l'objet, soit avec Nouveau, avec Object.create, ou basé sur le littéral (fonctions par défaut à Function.prototype, nombres à Number.prototype, etc.). Il ne peut être lu qu'avec Object.getPrototypeOf (someObject). Il y a non autre moyen de définir ou de lire cette valeur.

Fonctions, en plus du caché [[prototype]] propriété, ont également une propriété appelée prototype, et c'est ce que vous pouvez accéder, et modifier, pour fournir des propriétés héritées et des méthodes pour les objets que vous faites.


Voici un exemple:

ObjMaker = function() {this.a = 'first';};
// ObjMaker is just a function, there's nothing special about it that makes 
// it a constructor.

ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible prototype property that 
// we can alter. I just added a property called 'b' to it. Like 
// all objects, ObjMaker also has an inaccessible [[prototype]] property
// that we can't do anything with

obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called obj1.  At first obj1 was the same
// as {}. The [[prototype]] property of obj1 was then set to the current
// object value of the ObjMaker.prototype (if ObjMaker.prototype is later
// assigned a new object value, obj1's [[prototype]] will not change, but you
// can alter the properties of ObjMaker.prototype to add to both the
// prototype and [[prototype]]). The ObjMaker function was executed, with
// obj1 in place of this... so obj1.a was set to 'first'.

obj1.a;
// returns 'first'
obj1.b;
// obj1 doesn't have a property called 'b', so JavaScript checks 
// its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype
// ObjMaker.prototype has a property called 'b' with value 'second'
// returns 'second'

C'est comme l'héritage de classe parce que maintenant, tous les objets que vous faites en utilisant new ObjMaker() semblera également avoir hérité de la propriété 'b'.

Si vous voulez quelque chose comme une sous-classe, alors vous faites ceci:

SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);

SubObjMaker.prototype.c = 'third';  
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype

obj2.c;
// returns 'third', from SubObjMaker.prototype

obj2.b;
// returns 'second', from ObjMaker.prototype

obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype 
// was created with the ObjMaker function, which assigned a for us

J'ai lu une tonne d'ordures sur ce sujet avant de finalement trouver cette page, où cela est très bien expliqué avec de beaux diagrammes.


1958
2017-10-29 22:22



Supposons que vous avez cette fonction:

var Foo = function(){
  this.A = 1;
  this.B = 2;
};

Si vous appelez cela comme une fonction autonome comme ceci:

Foo();

L'exécution de cette fonction ajoutera deux propriétés au window objet (A et B). Il l'ajoute à la window car window est l'objet qui a appelé la fonction lorsque vous l'exécutez comme ça, et this dans une fonction est l'objet qui a appelé la fonction. En Javascript au moins.

Maintenant, appelez comme ça avec new:

var bar = new Foo();

Que se passe-t-il lorsque vous ajoutez new à un appel de fonction est qu'un nouvel objet est créé (juste var bar = new Object()) et que le this dans les points de fonction à la nouvelle Object vous venez de créer, au lieu de l'objet qui a appelé la fonction. Alors bar est maintenant un objet avec les propriétés A et B. Toute fonction peut être un constructeur, cela n'a pas toujours de sens.


359
2018-06-20 23:46



En plus de la réponse de Daniel Howard, voici ce que new fait (ou du moins semble faire):

function New(func) {
    var res = {};
    if (func.prototype !== null) {
        res.__proto__ = func.prototype;
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
        return ret;
    }
    return res;
}

Tandis que

var obj = New(A, 1, 2);

est équivalent à

var obj = new A(1, 2);

146
2018-05-27 09:23



Pour les débutants pour mieux le comprendre

essayez le code suivant dans la console du navigateur.

function Foo() { 
    return this; 
}

var a = Foo();       //returns window object
var b = new Foo();   //returns empty object of foo

a instanceof Window;  // true
a instanceof Foo;     // false

b instanceof Window;  // false
b instanceof Foo;     // true

Maintenant, vous pouvez lire la réponse du wiki de la communauté :)


85
2017-10-29 21:34



donc ce n'est probablement pas pour créer   instances d'objet

C'est utilisé exactement pour ça. Vous définissez un constructeur de fonction comme suit:

function Person(name) {
    this.name = name;
}

var john = new Person('John');

Cependant, l'avantage supplémentaire qu'ECMAScript a est que vous pouvez étendre avec le .prototype propriété, de sorte que nous pouvons faire quelque chose comme ...

Person.prototype.getName = function() { return this.name; }

Tous les objets créés à partir de ce constructeur auront maintenant un getName à cause de la chaîne de prototypes à laquelle ils ont accès.


33
2017-10-29 21:36



JavaScript est un langage de programmation orienté objet et il est utilisé exactement pour créer des instances. Il est basé sur un prototype, plutôt que sur une classe, mais cela ne signifie pas qu'il n'est pas orienté objet.


26
2017-10-29 21:37



Javascript est un langage de programmation dynamique qui prend en charge le paradigme de programmation orienté objet, et l'utilise pour créer de nouvelles instances d'objet.

Les classes ne sont pas nécessaires pour les objets - Javascript est un prototype basé la langue.


13
2018-05-16 07:21



parfois le code est plus facile que les mots:

var func1 = function (x) { this.x = x; }                    // used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; }   // used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;

A1 = new func1(1);      // has A1.x  AND  A1.y
A2 =     func1(1);      // undefined ('this' refers to 'window')
B1 = new func2(2);      // has B1.x  ONLY
B2 =     func2(2);      // has B2.x  ONLY

pour moi, tant que je n'ai pas de prototype, j'utilise le style de func2 car cela me donne un peu plus de flexibilité à l'intérieur et à l'extérieur de la fonction.


3
2017-10-29 21:38



le new mot-clé est pour créer de nouvelles instances d'objet. Et oui, javascript est un langage de programmation dynamique, qui supporte le paradigme de programmation orienté objet. La convention sur la dénomination de l'objet est, toujours utiliser la lettre majuscule pour les objets qui sont censés être instanciés par le nouveau mot-clé.

obj = new Element();

2
2017-10-05 02:28



Il y a déjà de très bonnes réponses mais j'en poste une nouvelle pour souligner mon observation sur le cas III ci-dessous à propos de ce qui se passe quand vous avez une déclaration de retour explicite dans une fonction que vous êtes newen place. Jetez un oeil sur les cas ci-dessous:

Cas I:

var Foo = function(){
  this.A = 1; 
  this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1

Ci-dessus est un cas simple d'appeler la fonction anonyme pointée par Foo. Lorsque vous appelez cette fonction, elle renvoie undefined. Comme il n'y a pas d'instruction de retour explicite, l'interpréteur JavaScript insère un return undefined; déclaration à la fin de la fonction. Ici, la fenêtre est l'objet d'invocation (contextuel this) qui obtient de nouvelles A et B Propriétés.

Cas II:

var Foo = function(){
  this.A = 1;
  this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1

Ici, l'interpréteur JavaScript voit le new mot-clé crée un nouvel objet qui agit comme objet d'invocation (contextuel this) de fonction anonyme pointée par Foo. Dans ce cas A et Bdeviennent des propriétés sur l'objet nouvellement créé (à la place de l'objet window). Comme vous n'avez aucune instruction de retour explicite, l'interpréteur JavaScript insère avec force une instruction return pour retourner le nouvel objet créé en raison de l'utilisation de new mot-clé.

Cas III:

var Foo = function(){
  this.A = 1;
  this.B = 2;
  return {C:20,D:30}; 
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.

Ici encore, l'interpréteur JavaScript voit le new mot-clé crée un nouvel objet qui agit comme objet d'invocation (contextuel this) de fonction anonyme pointée par Foo. Encore, A et B deviennent des propriétés sur l'objet nouvellement créé. Mais cette fois, vous avez une déclaration de retour explicite afin que l'interpréteur JavaScript ne pas faire quelque chose de son propre.

La chose à noter dans le cas III est-ce que l'objet est créé en raison de new mot-clé a été perdu de votre radar. bar est en train de pointer vers un objet complètement différent qui n'est pas celui que l'interpréteur JavaScript a créé en raison de new mot-clé.


2
2018-05-13 23:05



Bien JavaScript peut différer grandement d'une plate-forme à l'autre car il s'agit toujours d'une implémentation de la spécification originale EcmaScript.

Dans tous les cas, indépendamment de l'implémentation de toutes les implémentations JavaScript qui suivent la spécification EcmaScript, vous obtiendrez un langage orienté objet. Selon la norme ES:

ECMAScript est un langage de programmation orienté objet pour   effectuer des calculs et manipuler des objets de calcul   dans un environnement hôte.

Donc, maintenant que nous avons convenu que JavaScript est une implémentation d'EcmaScript, il s'agit donc d'un langage orienté objet. La définition du new opération dans un langage orienté objet, dit que ce mot-clé est utilisé pour créer une instance d'objet à partir d'une classe d'un certain type (y compris les types anonymes, dans des cas comme C #).

En EcmaScript, nous n'utilisons pas de classes, comme vous pouvez le lire dans les spécifications:

ECMAScript n'utilise pas de classes telles que C ++, Smalltalk ou Java. A la place, des objets peuvent être créés de différentes manières, y compris via   une notation littérale ou via des constructeurs qui créent des objets puis exécutent du code qui initialise tout ou partie d'eux en assignant initial   valeurs à leurs propriétés. Chaque constructeur est une fonction qui a un   propriété nommée -       prototype ‖ utilisé pour implémenter l'héritage basé sur le prototype et les propriétés partagées. Les objets sont créés par
  utiliser des constructeurs dans de nouvelles expressions; par exemple, nouveau   Date (2009,11) crée un nouvel objet Date. Invoquer un constructeur   sans utiliser de nouvelles conséquences qui dépendent du constructeur.   Par exemple, Date () produit une représentation sous forme de chaîne de   la date et l'heure actuelles plutôt qu'un objet.


1
2017-11-27 13:13