2016-05-22 5 views
5

Я читаю You Do not Know JS: ES6 & За пределами и я столкнулся с этим фрагментом в разделе Symbol.species.Что это в этом фрагменте?

class Cool { 
 
    // defer `@@species` to derived constructor 
 
    static get [Symbol.species]() { return this; } 
 

 
    again() { 
 
     return new this.constructor[Symbol.species](); 
 
    } 
 
} 
 

 
class Fun extends Cool {} 
 

 
class Awesome extends Cool { 
 
    // force `@@species` to be parent constructor 
 
    static get [Symbol.species]() { return Cool; } 
 
} 
 

 
var a = new Fun(), 
 
    b = new Awesome(), 
 
    c = a.again(), 
 
    d = b.again(); 
 

 
c instanceof Fun;   // true 
 
d instanceof Awesome;  // false 
 
d instanceof Cool;   // true

Похоже, что функция Symbol.species {вернуть что-то} всегда должен возвращать функцию конструктора. Но при первом присутствии этой функции: static get [Symbol.species]() { return this; } Я смущен, потому что я всегда думаю, что это должен быть объект вместо функции-конструктора. Не могли бы вы помочь мне прояснить факты?

И около return new this.constructor[Symbol.species]();, что здесь означает?

ответ

5

this будет ссылаться на что-то другое внутри метода в зависимости от контекста, который он выполнял.

В методах класса статические методы, this будут относиться к классу.

Так, например, с

static get [Symbol.species]() { return this; } 

Так как это метод класса, он будет выполнен на классе и this будет относиться к классу

//since this is a getter we don't use trailing `()` 
Cool[Symbol.species] === Cool; 
//It does not exist on instances 
var myCool = new Cool(); 
console.log(myCool[Symbol.species]); 
//will give undefined 

Теперь методы экземпляра, как и again, они существуют только на экземпляре и поэтому вызываются из экземпляра, а не класса:

console.log(Cool.again); 
//will give undefined 
var myCool = new Cool(); 
var newInstance = myCool.again(); 

В примерах методы this относится к экземпляру, а не к классу.

Так Дано:

return new this.constructor[Symbol.species](); 
  • this является экземпляром (например, new Cool)
  • this.constructor это конструктор, который создал экземпляр (например, Cool)
  • this.constructor[Symbol.species] метод класса геттер Symbol.species
  • new this.constructor[Symbol.species]() - новый экземпляр класс, возвращаемый Symbol.species

Таким образом, вся строка возвращает новый экземпляр класса, возвращаемого методом статического getter Symbol.species.

Это позволяет классу иметь методы, которые создают новые экземпляры класса, не зная его имени.

Так как пример показывает, хотя Fun никогда не определял свою собственную again метод again знает, как создать новый экземпляр Fun. А так как Awesome показывает, что вы можете просто переопределить Symbol.species, чтобы изменить то, что создаст экземпляр again.

Смежные вопросы