2015-06-28 27 views
20

In ES6, entrambe queste sono legali:metodi negli oggetti ES6: utilizzando le funzioni di freccia

var chopper = { 
    owner: 'Zed', 
    getOwner: function() { return this.owner; } 
}; 

e, come abbreviazione:

var chopper = { 
    owner: 'Zed', 
    getOwner() { return this.owner; } 
} 

E 'possibile utilizzare le nuove funzioni di direzione, nonché ? Nel cercare qualcosa di simile

var chopper = { 
    owner: 'John', 
    getOwner: => { return this.owner; } 
}; 

o

var chopper = { 
    owner: 'John', 
    getOwner: => (this.owner) 
}; 

ricevo un messaggio di errore che suggeriscono che il metodo non ha accesso a this. Si tratta solo di un problema di sintassi o non è possibile utilizzare i metodi di pipe grasse all'interno degli oggetti ES6?

+5

Uno dei maggiori punti della nuova sintassi della funzione era che tratta 'questo' in modo diverso. È definito dall'ambiente lessicale in cui è stata creata la funzione, il che significa che il valore 'this' in cui si crea la variabile' chopper' sarà il valore 'this' della funzione. In altre parole, non farà riferimento all'oggetto 'chopper'. –

+0

capito, c'è un modo per riscrivere questa funzione in modo che si riferisca a 'owner' all'interno di chopper? – fox

+1

Durante l'uso della sintassi della freccia grassa? Solo se modifichi il valore 'this' creando prima l'oggetto' chopper', quindi eseguendo l'assegnamento in una funzione che ha 'this' che punta a quell'oggetto. Questo può essere realizzato in modo abbastanza pulito con una funzione di costruzione. –

risposta

32

Le funzioni di freccia non sono progettate per essere utilizzate in ogni situazione semplicemente come una versione più breve di funzioni vecchio stile. Non intendono sostituire la sintassi della funzione utilizzando la parola chiave function. Il caso d'uso più comune per le funzioni a freccia è il breve "lambda" che non ridefinisce lo this, spesso usato quando si passa una funzione come callback a una funzione.

funzioni Freccia non possono essere usati per scrivere i metodi degli oggetti perché, come hai trovato, poiché le funzioni di direzione assumono il this del contesto funzione di lessicale che racchiude, il this all'interno di una definizione di un oggetto è o la finestra o qualcosa d'altro:

var foo = { 
    bar:() => this.baz // this is window or something else 
} 

Nel tuo caso, volendo scrivere un metodo su un oggetto, dovresti semplicemente usare lo standard function syntax, oi "nomi dei metodi abbreviati" introdotti in ES6.

C'è stato qualche dibattito sulla mailing list es6 su un twist sulle funzioni di freccia che hanno una sintassi simile ma con il proprio this. Tuttavia, questa proposta è stata scarsamente accolta perché si tratta semplicemente di zucchero sintattico, che consente alle persone di salvare la digitazione di pochi caratteri e non fornisce nuove funzionalità rispetto alla sintassi delle funzioni esistente. Vedere l'argomento unbound arrow functions.

una precedente proposta era quello di ridurre il numero di ictus utilizzando "corpi sintetici", che consente di non dover scrivere return, come in

var foo = { 
    function bar() this.baz 
        ^^^^^^^^ "concise body" 
} 

ma questo è stata respinta per motivi parseability.

+0

Se sto leggendo questo correttamente, sembra suggerire che la mailing list deprioritizza lo zucchero sintattico, anche se porterebbe a una maggiore uniformità/leggibilità del codice. Allo stato attuale, è molto più difficile utilizzare le funzioni fat-arrow in un contesto OOP in ES6 rispetto a, ad esempio, sotto coffeescript. – fox

+0

A quanto ho capito, lo zucchero sintattico ** è ** considerato un valido motivo per considerare le estensioni della lingua, ma come dici tu con una priorità più bassa - in altre parole, la barra è più alta per tali proposte. –

5

In questa linea getOwner: => (this.owner) dovrebbe essere:

var chopper = { 
    owner: 'John', 
    getOwner:() => this.owner 
}; //here `this` refers to `window` object. 

Si dovrebbe dichiarare this in una funzione:

var chopper = { 
    owner: 'John', 
    getOwner() { return this.owner } 
}; 

Oppure:

var chopperFn = function(){ 
 

 
    this.setOwner = (name) => this.owner = name; 
 
    Object.assign(this,{ 
 
     owner: 'Jhon', 
 
     getOwner:() => this.owner, 
 
    }) 
 

 
} 
 

 
var chopper = new chopperFn(); 
 
console.log(chopper.getOwner()); 
 
chopper.setOwner('Spiderman'); 
 
console.log(chopper.getOwner());

+1

Qui sto ricevendo un errore: '" TypeError: Impossibile leggere la proprietà 'owner' di undefined \ n su Object.chopper.getOwner' – fox

+0

Vedo, è l'uso corretto, tuttavia il metodo sempre restituisce la finestra Object. dovrebbe dichiarare 'this' all'interno di una funzione: –

+2

' questo 'non si riferisce necessariamente a' window'. Si riferisce a qualsiasi valore corrente di 'this' è nell'ambiente di chiusura, che può o non può essere' window "Forse è quello che volevi dire, voglio solo assicurarmi che lui capisca che non è un valore predefinito. –

Problemi correlati