为什么闭包编译器用google . exportsymbol重命名属性

Why does closure compiler renames property with goog.exportSymbol?

本文关键字:exportsymbol 重命名 属性 google 闭包 编译器 为什么      更新时间:2023-09-26

我使用Closure Compiler在线工具在高级模式下测试我的js代码。

我的代码片段如下:
// ==ClosureCompiler==
// @compilation_level ADVANCED_OPTIMIZATIONS
// @output_file_name default.js
// @formatting pretty_print
// ==/ClosureCompiler==
// ADD YOUR CODE HERE
/**
 * Base namespace for the Closure library.  Checks to see goog is
 * already defined in the current scope before assigning to prevent
 * clobbering if base.js is loaded more than once.
 *
 * @const
 */
var goog = goog || {}; // Identifies this file as the Closure base.
/**
 * Reference to the global context.  In most cases this will be 'window'.
 */
goog.global = this;
/**
 * Returns true if the specified value is not |undefined|.
 * WARNING: Do not use this to test if an object has a property. Use the in
 * operator instead.  Additionally, this function assumes that the global
 * undefined variable has not been redefined.
 * @param {*} val Variable to test.
 * @return {boolean} Whether variable is defined.
 */
goog.isDef = function(val) {
  return val !== undefined;
};
/**
 * Exposes an unobfuscated global namespace path for the given object.
 * Note that fields of the exported object *will* be obfuscated,
 * unless they are exported in turn via this function or
 * goog.exportProperty
 *
 * <p>Also handy for making public items that are defined in anonymous
 * closures.
 *
 * ex. goog.exportSymbol('public.path.Foo', Foo);
 *
 * ex. goog.exportSymbol('public.path.Foo.staticFunction',
 *                       Foo.staticFunction);
 *     public.path.Foo.staticFunction();
 *
 * ex. goog.exportSymbol('public.path.Foo.prototype.myMethod',
 *                       Foo.prototype.myMethod);
 *     new public.path.Foo().myMethod();
 *
 * @param {string} publicPath Unobfuscated name to export.
 * @param {*} object Object the name should point to.
 * @param {Object=} opt_objectToExportTo The object to add the path to; default
 *     is |goog.global|.
 */
goog.exportSymbol = function(publicPath, object, opt_objectToExportTo) {
  goog.exportPath_(publicPath, object, opt_objectToExportTo);
};
/**
 * Builds an object structure for the provided namespace path,
 * ensuring that names that already exist are not overwritten. For
 * example:
 * "a.b.c" -> a = {};a.b={};a.b.c={};
 * Used by goog.provide and goog.exportSymbol.
 * @param {string} name name of the object that this file defines.
 * @param {*=} opt_object the object to expose at the end of the path.
 * @param {Object=} opt_objectToExportTo The object to add the path to; default
 *     is |goog.global|.
 * @private
 */
goog.exportPath_ = function(name, opt_object, opt_objectToExportTo) {
  var parts = name.split('.');
  var cur = opt_objectToExportTo || goog.global;
  // Internet Explorer exhibits strange behavior when throwing errors from
  // methods externed in this manner.  See the testExportSymbolExceptions in
  // base_test.html for an example.
  if (!(parts[0] in cur) && cur.execScript) {
    cur.execScript('var ' + parts[0]);
  }
  // Certain browsers cannot parse code in the form for((a in b); c;);
  // This pattern is produced by the JSCompiler when it collapses the
  // statement above into the conditional loop below. To prevent this from
  // happening, use a for-loop and reserve the init logic as below.
  // Parentheses added to eliminate strict JS warning in Firefox.
  for (var part; parts.length && (part = parts.shift());) {
    if (!parts.length && goog.isDef(opt_object)) {
      // last part and we have an object; use it
      cur[part] = opt_object;
    } else if (cur[part]) {
      cur = cur[part];
    } else {
      cur = cur[part] = {};
    }
  }
};


//
// Application code
//
goog.exportSymbol('MyApp.util.test', function () {window.alert('It works!')});
MyApp.util.test();

复制并粘贴到闭包编译器中,然后点击编译。编译后的代码如下:

function a() {
  window.alert("It works!");
}
var b = ["MyApp", "util", "test"], c = this;
b[0] in c || !c.execScript || c.execScript("var " + b[0]);
for (var d;b.length && (d = b.shift());) {
  b.length || void 0 === a ? c = c[d] ? c[d] : c[d] = {} : c[d] = a;
}
MyApp.a.test();

可以看到MyApp.util.test()重命名为-> MyApp.a.test()。是虫子吗?因为我用了

goog.exportSymbol('MyApp.util.test', .....

闭包编译器应该将其保存在我的代码中,作为MyApp.util.test。怎么了?

MyApp.util。正在正确导出Test。如果你看这里的jsbin,你可以检查方法:http://jsbin.com/jajux/1/edit

它被重命名为MyApp.a.test,因为最初的调用发生在代码中,然后被编译。而它将被全局导出为MyApp。在编译后的代码中,它仍然可以被编译器重命名。