2013-02-27 2 views
0

Est-il possible, par tout moyen, de faire quelque chose comme ceci:Extensions de langage JavaScript avec des appels de fonction sans parenthèse - sont-ils possibles?

function A() { 
    var Loaded = 'loaded'; 
    raise Loaded; 
} 
function A_raise(evt) { 
    console.log(evt); 
} 
A.prototype.constructor = A; 
A.prototype.raise = A_raise; 

La partie critique étant la ligne:

raise Loaded; 
+0

Si c'est une partie critique, vous pourriez peut-être nous dire ce que vous entendez par 'raise' (car ce n'est pas un mot-clé JavaScript). Voulez-vous dire «jeter»? Si non, que veux-tu dire? –

+0

Si vous n'aimez pas la syntaxe _messy_ JavaScript, vous pouvez regarder les langues qui se compilent en JavaScript comme CoffeeScript. – Halcyon

+0

C'était juste un exemple, le but serait de créer un nouveau mot-clé nommé "raise" qui passe un paramètre à A_raise. – CoryG

Répondre

4

La seule façon d'obtenir une parenthèse-moins appel de fonction en JavaScript est de définir une propriété setter/getter, ou de remplacer l'une des méthodes spéciales: toString ou valueOf. Dans aucun des deux cas, vous n'avez un très bon contrôle sur le paramètre qui est transmis à l'appel.

function C() {} 
C.prototype.valueOf = function() { alert("valueOf called"); }; 
var c = new C(); 
// No parentheses 
+c; 

Vous pouvez appeler un constructeur sans parenthèses, mais à nouveau, ne pouvez pas passer d'arguments.

function f() { alert("f"); } 
// No parentheses 
new f 

Une raison pour laquelle vous ne pouvez pas la fonction d'insertion des points-virgules.

f() 

est un appel de fonction, comme

f 
() 

et

if 
(x) { } 

est une condition valide car if est une partie essentielle de la langue, mais si vous pouvez simplement laisser tomber les parenthèses à partir d'un appel de fonction puis l'insertion de point-virgule devrait traiter le code comme

var x = raise 

y 

en tant que variable initialisée au résultat de l'appel d'une fonction.


Depuis que vous avez demandé sur les extensions de langue, chapitre 16 de la spécification EcmaScript dit que les interprètes sont autorisés à ajouter à la grammaire de la langue,

Une mise en œuvre peut étendre la syntaxe du programme et modèle d'expression régulière ou la syntaxe d'indicateur. Pour permettre cela, toutes les opérations (appelant eval, utilisant un littéral d'expression régulière ou utilisant le constructeur Function ou RegExp) autorisées à lancer SyntaxError sont autorisées à afficher un comportement défini par l'implémentation au lieu de lancer SyntaxError lorsqu'elles rencontrent une implémentation. extension définie à la syntaxe du programme ou modèle d'expression régulière ou syntaxe d'indicateur.

donc depuis

raise foo 

n'est pas une expression valide ou une déclaration dans la langue, ils pourraient permettre, mais ils ne pouvaient pas le faire d'une manière qui change le sens de

raise 
foo 

qui doit avoir la même signification que

raise; 
foo 

que l'interprète devrait faire raise une nouvelle restricted production qui est problématique en raison du verbiage:

Voici les seules productions limitées dans la grammaire:

qui est probablement censé être non -normatif, mais ce n'est pas explicitement le cas.

+0

Je me rends compte qu'essayer d'ajouter un nouveau mot-clé à un langage de script est un peu à demander, donc je ne m'occupe pas d'un hack d'un moyen de le faire, mais avec les propriétés ne vous limitent pas à utiliser un signe égal?Je voudrais vraiment éviter d'utiliser des parenthèses ou des symboles - le but est "augmenter le chargement"; – CoryG

+0

@CoryG: Pas avec le JavaScript courant, non. Une propriété getter * presque * fonctionne (vous n'avez pas besoin d'un '='), mais vous ne pouvez pas lui passer d'argument (et cela devrait être 'this.raise Loading;' à quel point, vraiment, vous peut aussi bien lancer des parens). –

+0

Comment le réduire à "this.raise Loading"? J'ai été capable de le descendre pour "relancer" (Chargement); " ou "augmenter = Chargement" mais rien, mais un espace entre "augmenter" et "Chargement" est l'endroit où j'ai des problèmes. – CoryG

1

Vous ne pouvez pas définir de nouvelles instructions en JavaScript, vous ne pouvez donc pas créer la syntaxe que vous affichez dans A.

Modifier: De votre commentaire sur la question, il est clair que vous cherchez à définir une nouvelle déclaration/mot-clé. Non, vous ne pouvez pas faire ça.


réponse originale:

est votre objectif dans le constructeur A-appel la fonction A_raise? Si oui, vous êtes vraiment fermer. Il suffit de changer:

raise Loaded; 

à

this.raise(Loaded); 

Live Example | Source

Dans l'appel à une fonction constructeur via le mot-clé new, this est l'objet nouvellement construit, qui a déjà reçu son prototype de propriété prototype de la fonction constructeur. Donc, this aura raise dessus (via son prototype), et raise se référera à la fonction A_raise.

Mais encore une fois, vous avez besoin des parens (et le this.).

+0

Désolé, j'ai probablement laissé trop de détails dans le titre de l'article - le but est de créer un nouveau mot-clé nommé "raise" qui évite d'avoir à utiliser "this". ou entre parenthèses. – CoryG

+0

@CoryG: Oui, juste vu le commentaire sur la question et mis à jour. J'ai peur que tu ne puisses pas faire ça, non. –

Questions connexes