330 votes

La compréhension de la différence entre l'Objet.créer() et le nouveau SomeFunction() en JavaScript

Je suis récemment tombé sur l'Objet.méthode create() en JavaScript, et j'essaie d'en déduire comment il est différent de la création d'une nouvelle instance d'un objet " nouveau SomeFunction ()", et quand vous souhaitez utiliser l'un sur l'autre.

Considérons l'exemple suivant:

var test = {val: 1, func: function(){ return this.val; }};
var testA = Object.create(test);

testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2

console.log('other test');
var otherTest = function(){
    this.val = 1;
    this.func = function(){
        return this.val;
    };
};

var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB .val = 2;
console.log(otherTestA.val); // 1 
console.log(otherTestB.val); // 2

console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2

Notez que le même comportement est observé dans les deux cas. Il me semble que les principales différences entre ces deux scénarios sont les suivants:

  • L'objet utilisé dans l'Objet.créer constitue en fait le prototype de la nouvelle objet, où, comme dans la nouvelle Fonction() du formulaire de la déclaration de propriétés/fonctions ne font pas le prototype.
  • Vous ne pouvez pas créer des fermetures avec l'Objet.créer de la syntaxe, comme vous le feriez avec la syntaxe fonctionnelle. Ce qui est logique compte tenu de la lexicales (bloc vs) type de portée de JavaScript.

Sont les affirmations correctes? Et ai-je raté quelque chose? Quand voulez-vous utiliser l'un plutôt que l'autre?

EDIT: lien vers jsfiddle version de code ci-dessus, exemple: http://jsfiddle.net/rZfYL/

326voto

Evi1M4chine Points 509

Très simplement dit, new X est Object.create(X.prototype) avec en plus de l'exécution de l' constructor fonction. (Et de donner de l' constructor le chance d' return l'objet réel qui devrait être le résultat de l'expression à la place de this.)

C'est tout. :)

Le reste des réponses, c'est juste de la confusion, car apparemment personne d'autre lecture de la définition d' new . ;)

214voto

CMS Points 315406

L'objet utilisé dans l'Objet.créer constitue en fait le prototype de la nouvelle objet, où, comme dans la nouvelle Fonction() du formulaire de la déclaration de propriétés/fonctions ne font pas le prototype.

Oui, Object.create construit un objet qui hérite directement de celui passé en premier argument.

Avec des fonctions constructeur de l'objet nouvellement créé hérite du prototype du constructeur, par exemple:

var o = new SomeConstructor();

Dans l'exemple ci-dessus, o hérite directement de SomeConstructor.prototype.

Il y a une différence ici, avec Object.create vous pouvez créer un objet qui n'est pas hériter de quoi que ce soit, Object.create(null);, d'autre part, si vous définissez SomeConstructor.prototype = null; de l'objet nouvellement créé va hériter d' Object.prototype.

Vous ne pouvez pas créer des fermetures avec l'Objet.créer de la syntaxe, comme vous le feriez avec la syntaxe fonctionnelle. Ce qui est logique compte tenu de la lexicales (bloc vs) type de portée de JavaScript.

Eh bien, vous pouvez créer des fermetures, par exemple en utilisant la propriété des descripteurs argument:

var o = Object.create({inherited: 1}, {
  foo: {
    get: (function () { // a closure
      var closured = 'foo';
      return function () {
        return closured+'bar';
      };
    })()
  }
});

o.foo; // "foobar"

Notez que je parle de l'ECMAScript 5ème Édition Object.create méthode, pas la Crockford de la cale.

La méthode commence à être nativement mis en œuvre sur les navigateurs les plus récents, consultez ce tableau de compatibilité.

178voto

Ray Hulha Points 1072

new Test():

  1. créer new Object() obj
  2. ensemble obj.__proto__ de Test.prototype
  3. return Test.call(obj) || obj; // normally obj is returned but constructors in JS can return a value

Object.create( Test.prototype )

  1. créer new Object() obj
  2. ensemble obj.__proto__ de Test.prototype
  3. return obj;

Donc, fondamentalement, Object.create n'exécute pas le constructeur.

53voto

pandit Points 1454

@CMS réponse est génial. Je veux juste ajouter un exemple : Supposons que nous avons deux objets a et b.

var a = new Object();
var b = new Object();

Maintenant, a ont certaines méthodes b aussi souhaitez accéder.pour cela, nous avons besoin d'un objet d'héritage(a devrait être le prototype de l' b seulement de ce que nous pouvons accéder à ces méthodes).Si nous vérifions le prototype de l' a et b que nous allons découvrir qu'ils sont le prototype de l' Object.prototype.

Object.prototype.isPrototypeOf(b); //true
a.isPrototypeOf(b); //false (here problem comes in picture).

Problème - nous voulons objet a comme le prototype de l' b.mais ici nous avons créé un Objet b dont le prototype est Object.prototype. Solution - ECMAScript 5 introduire Object.create(), pour atteindre un tel aspect de l'héritage facilement.Si nous créons un Objet b comme ceci :

var b = Object.create(a);

que,

a.isPrototypeOf(b);// true (problem solved, you included Object a in prototype chain of Object b.)

Donc, si vous faites l'objet de script orienté qu' Object.create() est très utile pour l'héritage.

34voto

Leopd Points 12652

Ce:

var foo = new Foo();

et

var foo = Object.create(Foo.prototype);

sont assez similaires. Une différence importante est que l' new Foo exécute le code du constructeur, alors qu' Object.create de ne pas exécuter le code tel que

function Foo() {
    alert("This constructor does not run with Object.create");
}

Notez que si vous utilisez les deux paramètres de la version de Object.create() , alors vous pouvez faire beaucoup de choses plus puissantes.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by: