开发者

Scope of "this" in JavaScript

开发者 https://www.devze.com 2022-12-19 20:42 出处:网络
I have a JavaScript class that looks like this: function SomeFunction() { this.doSomething(function() { this.doSomethingElse();

I have a JavaScript class that looks like this:

function SomeFunction()
{
    this.doSomething(function()
    {
        this.doSomethingElse();
    });

    this.doSomethingElse = function()
    {

    }
}

This code throws an error because the scope of "this" inside the function that is passed into doSomething() is different that than the scope of "this" outside of that function.

I understand why this is, but what's the best way to deal with this? This is what I end up doing:

function SomeFunction()
{
    开发者_如何学编程var thisObject = this;

    this.doSomething(function()
    {
        thisObject.doSomethingElse();
    });

    this.doSomethingElse = function()
    {

    }
}

That works fine, but it just feels like a hack. Just wondering if someone has a better way.


That is the correct and commonly-accepted workaround. It's sort of kludgy but it's what everybody does. Typically this extra variable is named self, as in:

function SomeFunction()
{
    var self = this;

    this.doSomething(function()
    {
        self.doSomethingElse();
    });

    this.doSomethingElse = function()
    {

    }
}


this has dynamic "scope". That means that it is set up by whatever binds it, and this is bound by a "method call". That is, any time in your program you see this: w.f() then while f is executed, this is dynamically bound to f, even if f had this in its lexical scope.

Most JavaScript frameworks provide some facilities for dealing with this exact problem. With Prototype.js (for example) you can do this:

this.doSomething(function() { this.doSomethingElse(); }.bind(this));

Your "hack" however is fine. I usually do a (function (self) { ... })(this) around any functions that I need a lexically-scoped this-like variable.


It's also worth mentioning that the next version of ECMAScript (the language spec for JavaScript) is going to introduce Function.bind(), which will let you specify a permanent context for a function.


This commenter had what I was looking for (although the other answers are good too):

@Jon Kruger See this, check out their article for call, too: https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Apply– Jonathon 44 mins ago

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号