简体   繁体   English

为什么闭包编译器使用goog.exportSymbol重命名属性?

[英]Why does closure compiler renames property with goog.exportSymbol?

I use Closure Compiler online tool for testing of my js code in advanced mode. 我使用Closure Compiler在线工具在高级模式下测试我的js代码。

My code snippet is the following: 我的代码段如下:

// ==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();

Just copy and paste it into closure compiler and click compile. 只需将其复制并粘贴到闭包编译器中,然后单击编译。 The code after compiling is the following: 编译后的代码如下:

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();

As you can see MyApp.util.test() renamed into -> MyApp.a.test(). 如您所见,MyApp.util.test()重命名为-> MyApp.a.test()。 Is it bug? 是虫子吗? Because I use 因为我用

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

closure compiler should save this in my code as MyApp.util.test. 封闭编译器应将此代码保存为MyApp.util.test。 What's wrong? 怎么了?

MyApp.util.test is being exported properly. MyApp.util.test已正确导出。 If you look at a jsbin here you can inspect the method : http://jsbin.com/jajux/1/edit 如果您在这里查看jsbin,则可以检查该方法: http ://jsbin.com/jajux/1/edit

It is renamed to MyApp.a.test because that original call takes place inside the code which is then compiled. 它被重命名为MyApp.a.test,因为该原始调用发生在代码中,然后对其进行编译。 While it will be exported globally as MyApp.util, inside the compiled code it may still be renamed by the compiler. 尽管它将作为MyApp.util全局导出,但是在编译后的代码中,编译器仍可以将其重命名。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM