2015-12-29 30 views
6

Così ho dovuto vedermela con le classi ES6 quando ho visto qualcosa di sorprendente:Accesso ES6 proprietà eccellenti

class Animal { 
    constructor(name) { 
     this.name = name; 
    } 
    speak(sound) { 
     console.log(sound); 
    } 
} 

class Dog extends Animal { 
    constructor(name, age) { 
     super(name); 
     this.age = age; 
    } 
    speak() { 
     super.speak("Woof! I'm " + super.name + " and am " + this.age); 
    } 
} 

Poi, ho creato il mio cane:

var mydog = new Dog("mydog",3); 
mydog.speak(); 

Ora questo stampe

Woof! I'm undefined and am 3 

Quindi la mia domanda è: perché è super.name indefinito? Mi aspetto che sia mydog in questo caso.

+3

'super' può essere utilizzato solo per accedere alle proprietà sul prototipo. Usando 'this.name' che stai assegnando a * instance * e quindi devi sempre accedervi usando' this' – CodingIntrigue

risposta

9

this nel costruttore genitore riferisce ancora al cane, così this.name = name, imposta la proprietà name direttamente sull'oggetto Dog e non sul suo genitore. Utilizzando this.name funzionerà:

super.speak("Woof! I'm " + this.name + " and am " + this.age); 
+0

Hmm, non voglio duplicare le proprietà, dovrò aspettare 3 minuti prima di accettare questa risposta anche se – Downgoat

+1

Non sarà realmente duplicato, verrà creato solo sul Cane stesso. Se guardi la catena del prototipo del tuo cane vedrai: 'Cane {nome: 'mydog', età: 3} <- Cane {} <- Animale {} <- {}' – Paulpro

0

override un metodo su un'istanza di oggetto per chiamare il metodo prototipo con lo stesso nome, vorremmo fare qualcosa di simile

let person = { 
    getGreeting() { 
     return "Hello"; 
    } 
}; 

let dog = { 
    getGreeting() { 
     return "Woof"; 
    } 
}; 


let friend = { 
    getGreeting() { 
     return Object.getPrototypeOf(this).getGreeting.call(this) + ", hi!"; 
    } 
}; 

// set prototype to person 
Object.setPrototypeOf(friend, person); 
console.log(friend.getGreeting());      // "Hello, hi!" 
console.log(Object.getPrototypeOf(friend) === person); // true 

// set prototype to dog 
Object.setPrototypeOf(friend, dog); 
console.log(friend.getGreeting());      // "Woof, hi!" 
console.log(Object.getPrototypeOf(friend) === dog);  // true 

Utilizzando Object.getPrototypeOf() e .Call (questo) chiamare un metodo sul prototipo è un po 'lungo, beh ECMAScript 6 in soccorso e ha introdotto super. super è un puntatore al prototipo dell'oggetto corrente, uguale al valore Object.getPrototypeOf (this). Tenendo presente ciò, possiamo riscrivere il metodo getGreeting() come

let friend = { 
    getGreeting() { 
     // in the previous example, this is the same as: 
     // Object.getPrototypeOf(this).getGreeting.call(this) 
     return super.getGreeting() + ", hi!"; 
    } 
};