Câu hỏi này theo sau: Why does Closure compiler rename properties of an extern type? Câu trả lời của John cho câu hỏi đó sẽ trả về câu hỏi thứ hai này.Tôi có thể yêu cầu trình biên dịch Đóng cửa, chỉ với các loại cụ thể, ngừng đổi tên các thuộc tính?
Nếu tôi khai báo kiểu extern như đề xuất:
/** @interface */
function SpanishNoun() {}
/** @type {string} */
SpanishNoun.prototype.english;
/** @type {string} */
SpanishNoun.prototype.spanish;
sau đó Javascript như:
/**
* @param {SpanishNoun} n
*/
exp.foo = function (n) {
console.log(n.english, n.spanish, n['english'], n['spanish']);
}
sẽ biên dịch, như mong muốn, để:
function(a){console.log(a.english,a.spanish,a.english,a.spanish)};
Các tính chất không được đổi tên như bình thường. Nếu không có khai báo bên ngoài, mã được biên dịch sẽ trông giống như:
Tất cả đều tốt. Vấn đề là trình biên dịch đã ngừng đổi tên 'tiếng Anh' và 'tiếng Tây Ban Nha' ở tất cả các địa điểm. Ngay cả khi chúng không thuộc loại extern.
/**
* @param {AnotherType}
*/
exp.bar = function (c) {
c.other = c.english;
}
biên dịch để ...
function(a){a.b=a.english};
Có cách nào để ngăn chặn điều này? Nếu không, có lý do nào cho hành vi này không?
Tôi muốn sử dụng các loại bên ngoài để xử lý những thứ như đối tượng JSON có nguồn gốc từ máy chủ và không có thuộc tính được đổi tên. Nhưng nếu mỗi lần tôi tuyên bố một extern tôi đang ăn ở khả năng của trình biên dịch để đổi tên và thu nhỏ mã, tôi sẽ tìm một cách khác. Có lẽ tôi sẽ lấy bản đồ đổi tên thuộc tính được tạo bởi trình biên dịch (--property_map_output_file
) và sử dụng nó trên máy chủ khi tạo ra các phản hồi JSON.
Đây là hành vi tiêu chuẩn của Đóng cửa để tránh lỗi (bạn có thể đọc trang web Đóng cửa để hiểu tại sao điều này là cần thiết). Đóng cửa luôn đổi tên cùng một tên thuộc tính thành tên bị xé giống nhau. Mặt khác, nó không đổi tên tất cả các thuộc tính (bất kể ở đâu) cùng tên - bởi vì trong bản chất không đổi tên chỉ là đổi tên thành chính nó. Có một lá cờ (được gọi là "ambiguateProperties' hoặc một cái gì đó như thế) mà bạn có thể bật tránh điều này, nhưng nó chỉ là thử nghiệm. –
Lý do cho hành vi chuẩn này là bạn có thể viết một hàm chỉ lấy một đối tượng và sử dụng thuộc tính 'english' trên đối tượng đó. Đóng cửa không có cách nào để biết bạn đang đi qua đối tượng nào và liệu thuộc tính 'english' của đối tượng đó có được đổi tên hay không. Bởi vì JavaScript là một ngôn ngữ không gõ, bạn có thể thực hiện những thứ này (bằng cách truyền trong các đối tượng khác nhau của các lớp khác nhau), do đó trình biên dịch phải đổi tên cùng tên thuộc tính thành chuỗi giống nhau để tránh không thể quyết định phiên bản nào tên nó được ánh xạ tới. –