2017-05-12 1 views
2

Je joue avec javascript décorateurs mais je vais avoir du mal avec la cible qui est passé à la fonction décorateurQuel est le `target` dans les décorateurs javascript

Par exemple, si vous avez

@Bar() 
class Foo { 
    @deprecated(true) 
    doMagic() {} 
} 

function Bar() { 
    return function decorator(target) { 

    } 
} 

function deprecated(state) { 
    return function decorator(target, name, config) { 
     return config; 
    } 
} 

Je pense que les deux cibles s sont une seule et même chose, à droite, et ce n'est pas. Par exemple

function Bar() { 
    return function decorator(target) { 
     let bar = new target(); // WORKS 
     bar instanceof target; // -> true 
    } 
} 

function deprecated(state) { 
    return function decorator(target, name, config) { 
     let bar = new target(); // ERROR 
     let bar = new target.constructor() // WORKS 

     bar instanceof target; // ‌TypeError: Right-hand side of 'instanceof' is not callable 
     bar instanceof target.constructor // WORKS 
     return config; 
    } 
} 

Comme vous pouvez le voir, il y a une différence entre les deux cibles s, et ma question est ce qui ne va pas avec cette deuxième cible

J'utilise le noeud v7.8.0 et J'utilise les plugins babel de suivi (.babelrc)

{ 
    "presets": [ 
     "es2015", 
     "stage-0" 
    ] 

}

+1

Les décorateurs ne font pas partie de la norme ECMAScript et la phase actuelle est 2. https://github.com/tc39/proposals –

Répondre

1

On dirait que vous utilisez les anciens décorateurs. Méfiez-vous que le decorators proposal a évolué depuis et l'API est en constante évolution. La proposition est (au moment où j'écris ceci) à l'étape 2, p. "draft" (voir this document pour les détails).

Le target dans votre décorateur @deprecated utilisant l'ancien plug-in legacy est l'objet qui sera finalement sauvegardé comme Foo.prototype. Alors qu'au @Bar, c'est le constructeur de la classe Foo lui-même. C'est pourquoi dans votre décorateur @deprecated, vous ne pouvez pas utiliser new target (target est un objet non appelable), mais vous pouvez utiliser new target.constructor (qui est Object).

Mais encore une fois: Cette substance est toujours en flux.