2015-02-03 20 views
24

Có cách nào để sử dụng ký hiệu ECMAScript6 class để khai báo biến kiểu lớp tĩnh hoặc giá trị mặc định cho một biến mẫu không? Nếu không có class những gì tôi có trong tâm trí sẽ được viết nhưBiến thành viên trong các lớp ES6

function MyClass(arg) { if(arg) this.arg = arg; } 
MyClass.classVariable = 42; 
MyClass.prototype.arg = "no arg specified"; 

Rõ ràng nhất ES6 giống như ký hiệu theo ý kiến ​​của tôi sẽ là

class MyClass { 
    constructor(arg) { if(arg) this.arg = arg; } 
    static let classVariable = 42; 
    let arg = "no arg specified"; 
} 

Nhưng điều này không làm việc, kể từ khi theo the current spec draft sự chỉ các sản phẩm của ClassElement là các phương thức tĩnh và mẫu và dấu chấm phẩy. OK, người ta có thể sử dụng một cặp phương thức getter và setter để đạt được ngữ nghĩa tương tự với những gì tôi đã phác thảo, nhưng tôi đoán ở một hình phạt nghiêm trọng về hiệu năng và với cú pháp thực sự kì quái.

Có một số dự thảo đề xuất bao gồm các biến trong ký hiệu class, theo cách này hay cách khác không? Nếu vậy, cú pháp được đề xuất là gì, nó được xuất bản ở đâu, nó được thảo luận ở đâu, thảo luận diễn ra như thế nào, và tình trạng hiện tại của vấn đề ở mặt trận đó là gì? Vì nó là viết tắt, câu hỏi này không thể được trả lời nếu không có điều như vậy đã được thảo luận trước đây, ở cấp độ nào, nhưng tôi xem xét rằng không.


Một chút nền tảng: Tôi hiện đang đùa với trình biên dịch đóng trình biên dịch nâng cao của Google, sử dụng ES6 làm đầu vào. Để làm việc đó, tôi cần một chỗ để đặt chú thích kiểu cho biến thành viên, và tôi đã sử dụng chúng bằng cách sử dụng cú pháp như /** @type {string} */ MyClass.prototype.arg; là một ngữ nghĩa không có trong ECMAScript nhưng cung cấp thông tin kiểu cho trình biên dịch đóng cửa đẹp và dễ dàng. Tôi chưa tìm thấy một cách tương tự tốt đẹp để làm điều này với một cấu trúc class. Nhưng nếu bạn quan tâm đến việc giải quyết khía cạnh này, đó sẽ là một bình luận. Câu hỏi trên là về các khai báo thành viên không chỉ là số không, vì vậy đó là câu trả lời ở đây.

+2

Tôi nghĩ lớp 'Foo {get foo() {return 123}}' là càng gần vì nó được – kangax

+0

Tôi nghĩ kỹ thuật của @ kangax là đặt cược tốt nhất cho bất kỳ thứ gì sẽ hoạt động như một lớp trừu tượng. Tôi gặp vấn đề tương tự; đây là một bộ điều khiển tôi viết có thể/có thể không cung cấp cho bạn một số ý tưởng. Hàm khởi tạo của lớp cơ sở thực hiện tất cả việc nâng hạng nặng cho chức năng duy nhất (trong trường hợp này là mảng hợp nhất), vì vậy bạn phải đảm bảo rằng 'super()' luôn được gọi trên các hàm tạo lớp con: https://github.com/ affirmix/tungstenjs/blob/master/src/controller.js. Bạn có thể thấy rằng các lớp con không kết thúc quá khó chịu: https://github.com/affirmix/tungstenjs-todomvc/blob/master/src/todoitem-controller.j –

Trả lời

29

ES6 gần như chắc chắn sẽ không bao hàm cú pháp để xác định biến lớp. Chỉ có thể định nghĩa các phương thức và getters/setters bằng cách sử dụng cú pháp lớp. Điều này có nghĩa là bạn vẫn sẽ phải đi theo tuyến đường MyClass.classVariable = 42; cho các biến lớp.

Nếu bạn chỉ muốn khởi tạo một lớp với một số mặc định, có một bộ cú pháp mới được đặt cho đối số hàm và mặc định hủy bạn có thể sử dụng. Để cung cấp một ví dụ đơn giản:

class Foo { 
    constructor(foo = 123) { 
     this.foo = foo; 
    } 
} 

new Foo().foo == 123 
new Foo(42).foo == 42 
+0

Cách tiếp cận này không thực sự hiệu quả nếu bạn đang truy cập các thuộc tính lớp được đặt trong hàm tạo trong các hàm khác. Xem http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback – Jacob

+0

@Jacob trong ví dụ tôi đã cung cấp cho tôi không đặt thuộc tính lớp trong hàm tạo, nhưng thay vào đó là một thuộc tính cá thể có mặc định. Tuy nhiên, nếu bạn muốn truy cập một thuộc tính lớp từ bên trong một hàm trên cá thể, bạn có thể truy cập nó bằng cách sử dụng 'this.constructor.classProperty'. – lyschoening

+0

[Định nghĩa nội dung và phương pháp lớp] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Class_body_and_method_definitions) có ** Phương pháp thử nghiệm **. –

5

tôi đã không sử dụng Google Closure Compiler, nhưng với Babel bạn có thể khai static (scoped đến một class) biến như mô tả here. Bài viết tập trung vào React vì các tiện ích của static thành viên cho React, nhưng có thể áp dụng cho ES6 class es nói chung.

Cú pháp gần cú pháp đề xuất của bạn:

class MyClass { 
    constructor(arg) { if(arg) this.arg = arg; } 
    static defaultArg = 42; 
    let arg = MyClass.defaultArg; 
} 

Lưu ý rằng bạn sẽ có thêm 'es7.classProperties'-.babelrc bạn cho việc này để biên dịch. Xem Babel 5.0.0 release notes để biết thêm thông tin.

Tôi không biết liệu có cách nào để khai báo số static dưới dạng const hay không.

3

Mặc dù nó không phải là một phần của thông số ES6, có vẻ như nó sắp ra mắt và đã được Babel và một số người khác hỗ trợ.

Dưới đây là spec: https://github.com/jeffmo/es-class-fields-and-static-properties

Và một danh sách đầy đủ của tất cả các kiến ​​nghị và tình trạng của họ: https://github.com/tc39/ecma262

+0

"điều này có vẻ như nó đang đến trong ES7" nó chắc chắn không, bộ tính năng được hoàn thành và chỉ bao gồm 2 đề xuất giai đoạn-4. – zerkms

+0

@zerkms bạn hoàn toàn đúng, tôi đã sửa đổi câu trả lời của mình, cảm ơn bạn đã sửa! Tôi đã không nhận ra es7 đã được hoàn thành. –

Các vấn đề liên quan