2013-11-29 18 views
9

Các nguyên cảo sau:Enums trong TypeScript: mã JavaScript đang hoạt động như thế nào?

enum PrimaryColors { Red, Green, Blue }; 

Tạo JavaScript sau:

var PrimaryColors; 
(function (PrimaryColors) { 
    PrimaryColors[PrimaryColors["Red"] = 0] = "Red"; 
    PrimaryColors[PrimaryColors["Green"] = 1] = "Green"; 
    PrimaryColors[PrimaryColors["Blue"] = 2] = "Blue"; 
})(PrimaryColors || (PrimaryColors = {})); 
; 

Tôi xấu hổ khi thừa nhận rằng tôi không hiểu những gì JavaScript đang làm.
Hàm trong ngoặc đơn được gán giá trị chuỗi bằng cách sử dụng một phép gán khác làm chỉ mục/khóa. Tôi đã không nhìn thấy bất cứ điều gì như thế này trước đây.
Và mục đích của (PrimaryColors || (PrimaryColors = {}) theo chức năng?
Nếu câu trả lời là học JavaScript đúng cách, tôi sẽ sẵn sàng chấp nhận nó, miễn là nó đi kèm với nguồn gợi ý giải thích rõ ràng . những gì tôi nhìn thấy ở đây

Trả lời

9

tôi tin rằng:

PrimaryColors[PrimaryColors["Red"] = 0] = "Red"; 

tương đương với:.

PrimaryColors[0] = "Red"; 
PrimaryColors["Red"] = 0; 

Xem reference này

Biểu thức x = 7 là ví dụ về loại đầu tiên. Biểu thức này sử dụng toán tử = để gán giá trị 7 cho biến x. Biểu hiện tự đánh giá thành bảy.

Ví dụ:

console.log((x = 7)); 

kết quả đầu ra:

7 

Tương tự:

var x = {}; 
console.log((x["hi"] = 7)); 

Ngoài ra kết quả đầu ra 7.


Đối với điều thứ hai, PrimaryColors ban đầu không được xác định.

var x; 
console.log(x); // undefined 

Trong một bối cảnh boolean, undefined đánh giá để false:

console.log(!undefined); // true 
console.log(!!undefined); // false 

Sanity kiểm tra:

console.log((!undefined) === true); // true 
console.log((!!undefined) === false); // true 
console.log(undefined === false); // false 

Đây là một cách sử dụng phổ biến của mạch ngắn. Bởi vì PrimaryColors ban đầu không xác định (sai), nó sẽ vượt qua {} cho hàm.

PrimaryColors || (PrimaryColors = {}) 
+0

"..., nó sẽ chuyển {} vào hàm." phải là: "..., nó sẽ được khởi tạo thành một đối tượng trống, sau đó nó sẽ được chuyển đến hàm. –

7

Có thể điều này sẽ hữu ích.

(function() {})(); 

Đây là 'chức năng thực thi ngay lập tức'. Nó định nghĩa một hàm như là một biểu thức, và sau đó gọi nó.

var x = y || y = {}; 

Nếu mẫu chung để khởi tạo giá trị mặc định. Nếu y không có giá trị, phần đầu tiên của câu lệnh hoặc là sai, vì vậy nó thực hiện phần thứ hai, gán giá trị cho y. Giá trị của biểu thức thứ 2 là giá trị mới của y. Vì vậy x trở thành giá trị đó của y - đó là giá trị mới nếu nó chưa được xác định.

x[y] = z; 

Đối tượng trong JS là mảng kết hợp. Nói cách khác, các cặp chuỗi đối tượng, như IDictionary (chuỗi, đối tượng). Biểu thức này đang thiết lập khóa với giá trị y thành giá trị của z, trong từ điển x;

x[x["a"] = 0] = "a"; 

Vì vậy, điều tương tự ở đây, nhưng với một biểu thức lồng nhau, đó là:

x["a"] = 0; 

Vì vậy mà chỉ đặt giá trị của khóa "a". Không có gì lạ mắt. Nhưng điều này cũng là một biểu hiện, có giá trị là 0. Vì vậy, thay thế đó trong biểu thức ban đầu:

x[0] = "a"; 

Phím cần phải chuỗi, do đó, nó thực sự là điều tương tự như:

x["0"] = "a"; 

Mà chỉ đặt một khóa khác trong từ điển. Kết quả là các báo cáo này là đúng:

x["0"] === "a"; 
x["a"] === 0; 
0

Tôi thấy câu hỏi này bởi vì tôi đã tự hỏi tại sao sử dụng một IIFE ở tất cả khi bạn chỉ có thể init var với {} ngay đi. Các câu trả lời trước không bao gồm, nhưng tôi đã tìm thấy câu trả lời của mình trong số TypeScript Deep Dive.

Điều này là, enums có thể được chia thành nhiều tệp. Bạn chỉ cần phải khởi tạo một cách rõ ràng thành viên đầu tiên của thứ hai, thứ ba vv enums, vì vậy đây:

enum Colors { 
    Red, 
    Green, 
    Blue 
} 

enum Colors { 
    Cyan = 3, 
    Magenta, 
    Lime 
} 

transpiles này:

var Colors; 
(function (Colors) { 
    Colors[Colors["Red"] = 0] = "Red"; 
    Colors[Colors["Green"] = 1] = "Green"; 
    Colors[Colors["Blue"] = 2] = "Blue"; 
})(Colors || (Colors = {})); 
var Colors; 
(function (Colors) { 
    Colors[Colors["Cyan"] = 3] = "Cyan"; 
    Colors[Colors["Magenta"] = 4] = "Magenta"; 
    Colors[Colors["Lime"] = 5] = "Lime"; 
})(Colors || (Colors = {})); 

Như bạn đã biết, redeclaring một biến trong cùng một phạm vi là vô hại, nhưng reinitialization thì không.

Tôi nghĩ rằng họ có thể có lẽ chỉ cần đi:

var Colors; 
Colors || (Colors = {}); 
Colors[Colors["Cyan"] = 3] = "Cyan"; 
// ... 

và bỏ qua việc đóng cửa, nhưng có lẽ tôi vẫn đang thiếu một cái gì đó.

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