I have production code that I am now trying to minify with the Closure Compiler using the advanced option. The code uses Paul's client side cookie libraries. The compiler generates over 30 of these warnings:
JSC_USED_GLOBAL_THIS: dangerous use of the global this object
Here are some code snippets from Paul's library (oroginal code uses named functions, not anonymous functions):
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
The uc functions are typically constructed this way:
var ucRead = function () {
var search = this.name + "="
var CookieString = document.cookie
this.rawValue = null
this.found = false
}
I have read How does “this” keyword work within a JavaScript object literal? as well as Closure Compiler Warning dangerous use of the global "this" object? and Scope in JavaScript. However, I still don't understand what the scope of this
is in the above code nor how I would go about rewriting this code to eliminate the compiler warnings.
Q1: Can someone clarify for me what the scope of this
is?
Q2: Can someone provide some code snippets showing how the above can be rewritten to eliminate the compiler warnings (I assume the use of this
has to be eliminated)?
TIA.
The scope of
this
is, essentially, unpredictable.this
references whatever context in which the function is being called that particular call. For example:The basics are simple:
In the irst example there was no explicit owner object, so JS falls back to the global object, by default. (unless when using
strict mode
). The second example, foo was used as a method, called from the object, sothis
references that object.Now, this is all pretty easy but given that the
this
reference is determined ad hoc, and functions are loosely bound in JS (Array.prototype.slice.apply(arguments,[0]);
), There is no guarantee that this will always point to what you expect it to point to.ECMAScript 5 offers you the
bind
method for that, enabling you to bind a given context to a function object, but don't forget: there are some annoying people out there who still use outdated browsers.Besides, this is an "issue" which has been around for a long time, and people have used various workarounds. The easiest is the use of closures: