1

我有生产代码,现在我正在尝试使用高级选项使用 Closure Compiler 来缩小这些代码。该代码使用Paul 的客户端 cookie 库。编译器会生成 30 多个这样的警告:

JSC_USED_GLOBAL_THIS: dangerous use of the global this object

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

  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
  }

我已经阅读了“this”关键字在 JavaScript 对象文字中是如何工作的?以及关闭编译器警告危险使用全局“this”对象?JavaScript 中的范围。但是,我仍然不明白this上述代码的范围是什么,也不明白我将如何重写这段代码以消除编译器警告。

Q1:有人可以为我澄清一下范围this是什么吗?

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

TIA。

4

1 回答 1

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引用是临时确定的,并且函数在 JS ( ) 中的绑定松散Array.prototype.slice.apply(arguments,[0]);,因此无法保证this总是指向您期望它指向的内容。ECMAScript 5 为您提供了这种方法,使您能够将给定的上下文绑定到函数对象,但不要忘记:有些恼人的人仍在使用过时的浏览器。此外,这是一个由来已久的“问题”,人们使用了各种解决方法。最简单的是使用闭包:
bind

var MyConstructor = function()
{
    "use strict";//in strict mode, this'll throw errors when called without new keyword
    if (this === window || !this)
    {
        throw 'Omitted new keyword in older browsers, that don\'t support strict mode';
    }
    var that = this;//create closure reference to the new instance
    that.someProperty = 'Use that instead of this';
    that.especially = function()
    {
        console.log(this === that);//see later
        console.log('especially in methods, because they can be borrowed, at which point `this` could reference anything, but here: ' + that + ' Will always be what you expect');
    };
}
var foo = new MyConstructor();
foo.especially();//logs true, and 'especially in methods ...'
bar = [];
foo.especially.apply(bar,[]);//logs false, but the second log will still be the same
于 2012-10-28T14:12:17.597 回答