JavaScript“this”关键字和Closure Compiler警告

时间:2012-10-28 13:54:23

标签: javascript scope google-closure-compiler

我有生产代码,我现在正尝试使用高级选项缩小Closure Compiler。该代码使用Paul's client side cookie libraries。编译器生成超过30个这样的警告:

JSC_USED_GLOBAL_THIS: dangerous use of the global this object

以下是Paul的库中的一些代码片段(oroginal代码使用命名函数,而不是匿名函数):

  var cookieObject = function (name, expires, accessPath) {
        var i, j
        this.name = name
        this.fieldSeparator = "#"
        // this.found = false
        this['found'] = false;  // don't allow Closure-Compiler to rename
        this.expires = expires
        this.accessPath = accessPath
        this.rawValue = ""
        this.fields = new Array()
        this.fieldnames = new Array() 
        if (arguments.length > 3) { // field name(s) specified
              j = 0
              for (i = 3; i < arguments.length; i++) {
                    this.fieldnames[j] = arguments[i]    
                    j++
              }
              this.fields.length = this.fieldnames.length 
        }
        this.read = ucRead            // function assignments
        this.write = ucWrite
        this.remove = ucDelete
        this.get = ucFieldGet
        this.put = ucFieldPut
        this.namepos = ucNamePos
        this.read()
  }; // cookieObject

uc 函数通常以这种方式构造:

  var ucRead = function () {
        var search = this.name + "="
        var CookieString = document.cookie
        this.rawValue = null
        this.found = false
  }

我已阅读How does “this” keyword work within a JavaScript object literal?以及Closure Compiler Warning dangerous use of the global "this" object?Scope in JavaScript。但是,我仍然不明白上面的代码中this的范围是什么,也不知道如何重写此代码以消除编译器警告。

Q1:有人可以向我澄清this的范围是什么吗?

Q2:有人可以提供一些代码片段,说明如何重写上述内容以消除编译器警告(我假设必须消除this的使用)?

TIA。

1 个答案:

答案 0 :(得分:2)

this的范围基本上是不可预测的。 this引用函数被称为特定调用的任何上下文。例如:

var foo = function()//or function foo()
{
    console.log(this);
};
foo();//logs the window object
var anObj = {name:'someObject',method:foo};
anObj.method();//logs `anObj`

基础很简单:

[[someObject]].function();//call func
    /\            ||
    ||  implicit  ||
    |______________|

在第一个示例中,没有显式所有者对象,因此默认情况下JS会回退到全局对象。 (除非使用strict mode)。第二个例子,foo被用作从对象调用的方法,因此this引用该对象。

现在,这很容易,但鉴于this引用已确定 ad hoc ,并且函数松散绑定在JS中{{1 }}),无法保证总是指向您期望它指向的内容。
ECMAScript 5为您提供Array.prototype.slice.apply(arguments,[0]);方法,使您能够给定的上下文绑定到函数对象,但不要忘记:那里有一些讨厌的人谁仍然使用过时的浏览器。
此外,这是一个“问题”已经存在了很长时间,人们已经使用了各种解决方法。最简单的是使用闭包:

bind