2016-05-22 18 views
5

Tôi đang đọc Bạn không biết JS: ES6 & Ngoài và tôi đã gặp đoạn mã này trong phần Symbol.species.Điều này trong đoạn mã này là gì?

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

Nó có vẻ như các Symbol.species chức năng {return Something} nên luôn luôn trả về một hàm constructor. Nhưng trong sự hiện diện đầu tiên của chức năng này: static get [Symbol.species]() { return this; } Tôi bối rối vì tôi luôn nghĩ rằng đây phải là một đối tượng thay vì hàm xây dựng. Bạn có thể giúp tôi làm rõ sự thật không?

Và khoảng return new this.constructor[Symbol.species]();, nội dung này ở đây đề cập đến điều gì?

Trả lời

5

this sẽ đề cập đến nội dung nào đó khác bên trong phương thức tùy thuộc vào ngữ cảnh được thực hiện.

Trong phương pháp lớp học, phương pháp tĩnh, this sẽ tham chiếu đến lớp học.

Vì vậy, ví dụ với

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

Vì đây là một phương pháp học, nó sẽ được thực thi trên lớp và this sẽ tham khảo các lớp

//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 

Bây giờ cho các phương pháp dụ, như Phương pháp again, chúng chỉ tồn tại trên cá thể và được gọi từ cá thể và không được gọi là lớp:

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

Trong các phương thức ví dụ this là trường hợp, không phải là lớp.

Vì vậy, đưa ra:

return new this.constructor[Symbol.species](); 
  • this là trường hợp (ví dụ, new Cool)
  • this.constructor là các nhà xây dựng đã tạo ra dụ (ví dụ, Cool)
  • this.constructor[Symbol.species] là phương pháp lớp getter Symbol.species
  • new this.constructor[Symbol.species]() là phiên bản mới của lớp mà Symbol.species trả về

Vì vậy, toàn bộ dòng sẽ trả về một phiên bản mới của lớp mà phương thức trả về tĩnh trả về.

Điều này cho phép một lớp có các phương thức tạo ra các phiên bản mới của một lớp mà không biết tên của nó.

Vì vậy, làm ví dụ cho thấy, mặc dù Fun không bao giờ được xác định riêng again phương pháp của nó again biết làm thế nào để tạo một đối tượng mới của Fun. Và như Awesome cho thấy bạn chỉ có thể ghi đè Symbol.species để thay đổi những gì thể hiện again sẽ tạo ra.