2010-08-27 8 views
11

Je comprends la différence dans comportement. Date() renvoie une chaîne représentant la date actuelle et new Date() renvoie une instance de l'objet Date dont je peux appeler les méthodes. Mais je ne sais pas pourquoi. JavaScript est prototypé, donc Date est une fonction et un objet qui a des fonctions membres (méthodes) qui sont aussi des objets. Mais je n'ai pas écrit ou lu de JavaScript qui se comporte de cette façon, et j'aimerais comprendre la différence.Pourquoi ai-je besoin du mot-clé `new` pour une instance de` Date` en JavaScript?

Quelqu'un peut-il me montrer un exemple de code d'une fonction qui a une méthode, renvoie une instance avec le nouvel opérateur, et sort un String lorsqu'il est appelé directement? c'est-à-dire comment se passe-t-il quelque chose comme ça?

Date();     // returns "Fri Aug 27 2010 12:45:39 GMT-0700 (PDT)" 
new Date();    // returns Object 
new Date().getFullYear(); // returns 2010 
Date().getFullYear();  // throws exception! 

Demande très spécifique, je sais. J'espère que c'est une bonne chose. :)

+3

Re * pourquoi *: c'est un Hango malheureux ver de l'implémentation JavaScript originale qui l'a fait dans la spécification ECMAScript: http://bclary.com/2004/11/07/#a-15.9.2 –

+0

Ooh! Merci. J'aime le contexte et l'histoire. C'est bon _why_. :) –

+0

Merci @Crescent. J'ai incorporé ceci dans ma réponse pour l'exhaustivité. –

Répondre

3

La plupart de ceci est possible de faire vous-même. Appeler le constructeur nu sans new et obtenir une chaîne est spécial pour Date par la spécification ECMA, mais vous pouvez simuler quelque chose de similaire pour cela.

Voici comment vous le feriez. Tout d'abord déclarer un objet dans le modèle du constructeur (par exemple, une fonction qui est destinée à être appelée avec new et qui retourne sa this référence.

var Thing = function() { 
    // Check whether the scope is global (browser). If not, we're probably (?) being 
    // called with "new". This is fragile, as we could be forcibly invoked with a 
    // scope that's neither via call/apply. "Date" object is special per ECMA script, 
    // and this "dual" behavior is nonstandard now in JS. 
    if (this === window) { 
     return "Thing string"; 
    } 

    // Add an instance method. 
    this.instanceMethod = function() { 
     alert("instance method called"); 
    } 

    return this; 
}; 

De nouvelles instances de chose peut avoir instanceMethod() appelé sur eux Maintenant, il suffit d'ajouter un " fonction statique » sur elle-même chose:

Thing.staticMethod = function() { 
    alert("static method called"); 
}; 

maintenant, vous pouvez faire ceci:

var t = new Thing(); 
t.instanceMethod(); 
// or... 
new Thing().instanceMethod(); 
// and also this other one.. 
Thing.staticMethod(); 
// or just call it plain for the string: 
Thing(); 
+0

Mais 'Thing()' ne fait rien dans un contexte statique. Est-ce que Date détecte simplement si elle est appelée dans un contexte statique et renvoie une chaîne à la place d'un objet? Si c'est le cas, comment? –

+0

Votre modification le rend clair. Je vous remercie. –

+0

Voir la mise à jour. C'est une bonne question. Commentaire de Per @ Crescent sur la question initiale, il semble que 'Date' est spécial. Vous pouvez réaliser quelque chose comme ça vous-même comme ci-dessus, mais s'il vous plaît ne le faites pas.Ce n'est pas un idiome d'usage commun dans JS. –

0

new est un mot-clé dans Javascript (et autres) pour créer une nouvelle instance d'un objet.
Peut-être dupliquer de What is the 'new' keyword in JavaScript?.
Voir aussi cet article: http://trephine.org/t/index.php?title=Understanding_the_JavaScript_new_keyword

+0

Juste une supposition ici, mais je ne pense pas que le problème ici est que le nouveau reviendra et objectera. C'est plutôt le fait que Date() peut être appelée sans d'abord créer une instance. (pour une utilisation limitée, j'avoue) Pour obtenir la fonctionnalité de date complète, vous devez créer une instance avec new. – Tom

+0

Je sais ce que «nouveau» fait (et je pense que je l'ai dit clairement dans ma question). Je ne sais pas pourquoi la fonction se comporte différemment lorsqu'elle est appelée en tant que constructeur et en tant que fonction statique. Je veux connaître la syntaxe qui provoque cette distinction. –