2015-12-29 3 views
6

Так что я бездельничал с классами ES6, когда я увидел что-то удивительное:Доступ ES6 супер свойства

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); 
    } 
} 

Затем я создал мою собаку:

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

Теперь это печатает

Woof! I'm undefined and am 3 

Так что мой вопрос в том, почему super.name не определено? В этом случае я ожидаю, что это будет mydog.

+3

'super' может быть использован только для доступа к свойствам на прототипе. Используя 'this.name' вы назначаете * экземпляр *, и поэтому всегда нужно обращаться к нему с помощью' this' – CodingIntrigue

ответ

9

this в родительский конструктор по-прежнему относится к собаке, поэтому this.name = name, устанавливает свойство name непосредственно на Dog объекта, а не на его родителя. Использование this.name будет работать:

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

Хмм, я не хочу дублировать свойства, мне нужно подождать 3 минуты, прежде чем принимать этот ответ хотя – Downgoat

+1

На самом деле это не будет дублироваться, оно будет создано только на самой Собаке. Если вы посмотрите на цепочку прототипов вашей собаки, вы увидите: «Dog {name: 'mydog', age: 3} <- Dog {} <- Animal {} <- {}' – Paulpro

0

Переопределение метода на примере объекта для вызова метода прототип одного и того же имени, мы хотели бы сделать что-то вроде

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 

Использование Object.getPrototypeOf() и .call (это), чтобы вызвать метод на прототипе, немного длинный, хорошо ECMAScript 6 для спасения, и он ввел super. super - указатель на прототип текущего объекта, то же, что и значение Object.getPrototypeOf (this). Имея это в виду, мы можем переписать метод getGreeting(), как

let friend = { 
    getGreeting() { 
     // in the previous example, this is the same as: 
     // Object.getPrototypeOf(this).getGreeting.call(this) 
     return super.getGreeting() + ", hi!"; 
    } 
}; 
Смежные вопросы