Take the 2-minute tour ×

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]    
              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
  }; // 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)?


share|improve this question
this can be quite confusing and tricky at first (and can still catch you off guard later on, when you think you get it). But MDN provides a lot of info to get you started –  Elias Van Ootegem Oct 28 '12 at 13:57
add comment

1 Answer

up vote 2 down vote accepted

The scope of this is, essentially, unpredictable. this references whatever context in which the function is being called that particular call. For example:

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

The basics are simple:

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

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, so this 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:

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
share|improve this answer
Thank you. FYI: Your suggestion to use a closure led to these questions: Details on returning an object literal from a closure in JavaScript –  Karl Oct 29 '12 at 21:37
In addition, the compiler rewrites code in unexpected ways which often change the object to which the this keyword refers. See closuretools.blogspot.com/2012/09/… –  Chad Killingsworth Nov 2 '12 at 13:54
@ChadKillingsworth: thanks for the link, I guess the name says it all: if you want your code to work, use closures as much as you can :). –  Elias Van Ootegem Nov 2 '12 at 14:01
add comment

Your Answer


