In es6 können Sie ein solches Funktionsmodul definieren
export default {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { foo(); bar() }
}
Der obige Code scheint ein gültiger Code zu sein, aber wenn ich baz()
ihn aufrufe, wird ein Fehler ausgegeben:
ReferenceError: foo is not defined
Wie ruft man foo
von einer anderen Funktion aus auf? in diesem Fallbaz
Bearbeiten
Hier ist der Code, der eigentlich nicht funktioniert. Ich habe den Code so vereinfacht, dass er bei Bedarf nur der Kern ist
const tokenManager = {
revokeToken(headers) {
...
},
expireToken(headers) {
...
},
verifyToken(req, res, next) {
jwt.verify(... => {
if (err) {
expireToken(req.headers)
}
})
}
}
export default tokenManager
und der Fehler ist
expireToken(req.headers);
^
ReferenceError: expireToken is not defined
Bearbeiten 2
Ich Hinzufügen gerade versucht , tokenManager
bevor expireToken
es schließlich funktioniert
javascript
ecmascript-6
chrs
quelle
quelle
expireToken(req.headers)
mittokenManager.expireToken(req.headers)
oder mitthis.expireToken(req.headers)
.Antworten:
Die
export default {...}
Konstruktion ist nur eine Abkürzung für so etwas:const funcs = { foo() { console.log('foo') }, bar() { console.log('bar') }, baz() { foo(); bar() } } export default funcs
Es muss jetzt offensichtlich geworden , dass es keine
foo
,bar
oderbaz
Funktionen im Rahmen des Moduls. Es gibt jedoch ein Objekt mit dem Namenfuncs
(obwohl es in Wirklichkeit keinen Namen hat), das diese Funktionen als Eigenschaften enthält und zum Standardexport des Moduls wird.Um Ihren Code zu reparieren, schreiben Sie ihn neu, ohne die Verknüpfung zu verwenden, und verweisen Sie auf
foo
undbar
als Eigenschaften vonfuncs
:const funcs = { foo() { console.log('foo') }, bar() { console.log('bar') }, baz() { funcs.foo(); funcs.bar() } // here is the fix } export default funcs
Eine andere Möglichkeit besteht darin, ein
this
Schlüsselwort zu verwenden, um auf einfuncs
Objekt zu verweisen, ohne es explizit deklarieren zu müssen, wie @pawel hervorgehoben hat .Eine weitere Option (und die, die ich im Allgemeinen bevorzuge) besteht darin, diese Funktionen im Modulbereich zu deklarieren. Dies ermöglicht es, direkt auf sie zu verweisen:
function foo() { console.log('foo') } function bar() { console.log('bar') } function baz() { foo(); bar() } export default {foo, bar, baz}
Wenn Sie den Standard-Export und die Möglichkeit zum individuellen Importieren von Elementen nutzen möchten , können Sie auch alle Funktionen einzeln exportieren:
// util.js export function foo() { console.log('foo') } export function bar() { console.log('bar') } export function baz() { foo(); bar() } export default {foo, bar, baz} // a.js, using default export import util from './util' util.foo() // b.js, using named exports import {bar} from './util' bar()
Oder, wie @loganfsmyth vorgeschlagen hat, können Sie auf den Standardexport verzichten und nur verwenden
import * as util from './util'
, um alle benannten Exporte in einem Objekt abzurufen .quelle
expireToken
mittokenManager.expireToken
.export default { foo, bar, baz }
) und würde ihn wahrscheinlich selbst verwenden.import * as util from './util'
. Genau dafür wurden Namespace-Importe gemacht.Eine Alternative besteht darin, Ihr Modul zu wechseln. Wenn Sie ein Objekt mit einer Reihe von Funktionen exportieren, ist es im Allgemeinen einfacher, eine Reihe benannter Funktionen zu exportieren, z
export function foo() { console.log('foo') }, export function bar() { console.log('bar') }, export function baz() { foo(); bar() }
In diesem Fall exportieren Sie alle Funktionen mit Namen, damit Sie dies tun können
import * as fns from './foo';
So erhalten Sie ein Objekt mit Eigenschaften für jede Funktion anstelle des Imports, den Sie für Ihr erstes Beispiel verwenden würden:
import fns from './foo';
quelle
tl; dr:
baz() { this.foo(); this.bar() }
In ES2015 dieses Konstrukt:
var obj = { foo() { console.log('foo') } }
entspricht diesem ES5-Code:
var obj = { foo : function foo() { console.log('foo') } }
exports.default = {}
Wenn Sie ein Objekt erstellen, wird Ihr Standardexport wie folgt in ES5-Code übersetzt:exports['default'] = { foo: function foo() { console.log('foo'); }, bar: function bar() { console.log('bar'); }, baz: function baz() { foo();bar(); } };
Jetzt ist es irgendwie offensichtlich (ich hoffe), dass
baz
versucht wird, irgendwo im äußeren Bereich aufzurufenfoo
und zubar
definieren, die undefiniert sind. Aberthis.foo
undthis.bar
wird in die imexports['default']
Objekt definierten Schlüssel aufgelöst . Der Standardexport, der auf seine eigenen Methoden verweist, sieht also folgendermaßen aus:export default { foo() { console.log('foo') }, bar() { console.log('bar') }, baz() { this.foo(); this.bar() } }
Siehe babel repl transpiled Code .
quelle
TypeError: Cannot read property 'foo' of undefined
- was fehlt mir?