JavaScript “this” keyword and Closure Compiler warnings

那年仲夏 提交于 2019-12-02 03:51:38

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()
{
    console.log(this);
};
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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!