[英]Closure Compiler does not always inline enums. Why?
Google的Closure Compiler遵循哪些規則來決定enum
是否內聯?
當我通過Closure Compiler運行我的代碼時,JSDoc 注釋 enum
類型沒有內聯。 然而,當我創建一個簡化的示例時, enum
類型是內聯的,因為這個無意義的示例將演示:
var my_name_space = (function () {
'use strict';
/** @enum {number} */
var TASK_STATUS = {
REJECT: -1,
UNKNOWN: 0,
APPROVE: 1
};
function init_(a) {
if (a === TASK_STATUS.UNKNOWN) {
alert("Reject");
a = TASK_STATUS.REJECT;
} else if (a === TASK_STATUS.APPROVE) {
alert("Unknown");
a = TASK_STATUS.UNKNOWN;
} else {
alert("Approve");
a = TASK_STATUS.APPROVE;
}
return a;
}
return { init: init_};
}()); // my_name_space
my_name_space.init(-1);
關閉的輸出:
var my_name_space=function(){return{init:function(a){0===a?(alert("Reject"),a=-1):1===a?(alert("Unknown"),a=0):(alert("Approve"),a=1);return a}}}();my_name_space.init(-1);
實際上,在襯里中會出現或不出現JSDoc標頭。
請解釋襯里在什么條件下不會發生,甚至更好,請對上面的內容進行修改,以證明襯里不會發生。
我正在使用'簡單'優化級別。
首先,枚舉不是用於優化目的的特殊對象,但是,@ enum對於類型檢查很有用,並且具有用於該目的的特殊規則。
至於內聯,有很多東西可以阻止內聯,展示所有可能性是不合理的,但我可以告訴你為什么它們可能不是:
這些都歸結為編譯器無法確定它可以:
也就是說,如果你有一個簡單的局部定義,並且你只引用了值而不是對象本身,並且值本身就是簡單的常量(數字,布爾值),它總是會被內聯。
首先,我相信你必須使用ADVANCED_OPTIMIZATIONS從內聯獲得任何勝利。 您當前的代碼目前對ADVANCED OPTIMIZATIONS無效,因此我進行了修改以使其正常工作。
/** @enum {number} @const */
var TASK_STATUS = {
REJECT: -1,
UNKNOWN: 0,
APPROVE: 1
};
/**
* @param {TASK_STATUS} a
*/
function init_(a) {
if (a === TASK_STATUS.UNKNOWN) {
alert("Reject");
} else if (a === TASK_STATUS.APPROVE) {
alert("Unknown");
} else {
alert("Approve");
}
}
init_(TASK_STATUS.REJECT);
輸出:
alert("Approve");
閉包編譯器無法內聯代碼的原因有幾個原因。 Closure編譯器不會一直深入到您的代碼中 - 它通常使用您傳入的類型信息來做出決策。 通過對象表達式傳遞函數效果不佳。 (即,通過對象文字傳回init函數)
其次,你的init函數有副作用(分配a)。 由於閉包編譯器不知道什么是真正被改變的(沒有類型信息),它做了安全的事情,並沒有內聯函數。
高級模式下的Closure編譯器是一個野獸。 這需要一些時間來適應。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.