【问题标题】:JavaScript "this" keyword and Closure Compiler warningsJavaScript“this”关键字和闭包编译器警告
【发布时间】:2012-10-28 13:54:22
【问题描述】:

我现在正在尝试使用高级选项使用闭包编译器缩小生产代码。代码使用Paul's client side cookie libraries。编译器会生成 30 多个这样的警告:

JSC_USED_GLOBAL_THIS: dangerous use of the global this object

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

  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:有人可以提供一些代码 sn-ps 显示如何重写上述代码以消除编译器警告(我假设必须消除使用 this)?

TIA。

【问题讨论】:

标签: javascript scope google-closure-compiler


【解决方案1】:

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
相关资源
最近更新 更多