What is the rationale for the behavior of the 'this' keyword in JavaScript?

前端 未结 7 796
感动是毒
感动是毒 2020-12-13 00:59

I am asking this from a language design point of view. So I am trying to find out

  1. What is the rationale for the behavior of this?
  2. To what
相关标签:
7条回答
  • Consider the idiom a.f() as a shorthand for:

    a.f.call(a);
    

    It's by definition a call to the function f, using scope a.

    var f = a.f;
    f(); // f.call(this);
    a.f(); // f.call(a);
    

    If this and a are not the same object, f() and a.f() will use different scopes and therefore may behave differently. Consider the distinction between static and class methods in other languages:

    class Foo {
    public:
        static void a(Foo *scope) {
            // do something with given scope
        };
    
        void b() {
            a(this); // do something with the scope of this object
        };
    };
    
    Foo foo;
    Foo bar;
    
    foo.a(&bar) != foo.b(); // just like f() != a.f()
    foo.a(&foo) == foo.b(); // just like f.call(a) == a.f()
    
    0 讨论(0)
  • 2020-12-13 01:46

    You seem to be expecting this to behave as it does in certain OO languages, where it always refers to the object a method belongs to.

    But in JavaScript, a function can be attached to multiple objects, or no object at all. In your example, you've written a function intended to be used in the context of one specific object... But nothing prevents me from taking that function and attaching it to any other object. That's just the nature of the language - functions are first-class, object membership is optional.

    Therefore, this refers to the context in which a function is called. Right now, that's either an arbitrary object (specified via ., .apply, or .call()) or the global object. In future versions of the language, it will refer to the context in which the function was defined: the global object for global functions, the outer this for inner functions; you can view this as a correction of a design flaw, as in practice being able to refer to the global object using this was not particularly useful.

    0 讨论(0)
  • 2020-12-13 01:51

    I think unbound "this" is a mistake. Otherwise it is quite handy. Unbound "this" opens the possibility of misinterpreting the context most prominently apparent in event handling of browsers. Also javascript libraries have different opinions of what "this" should refer to in event handling and many callback constructs (like map, filter).

    Removing unbound "this" probably wouldn't make things any more difficult.

    Edit: I guess an alternative syntax example will make my stance clearer.

    function Foo()
    {
        //both this refer to the Foo instance
        this.blah=this.function(){this.bar;};
    
        //second this refers to baz
        this.blah=baz.function(){this.bar;};
    
        //second this refers to anonymous function itself
        this.blah=function(){this.bar;};
    }
    
    0 讨论(0)
  • 2020-12-13 01:53

    I think the unbound 'this' keyword is necessary because JavaScript is a prototype-based language. Someone better informed can probably fill in the details here.

    The fact that it is, is mightily unhelpful though. Especially if you want to pass the method of an object to a higher-order function, things start to get ugly (following examples with a little help from MooTools):

    myArray.each(myObject.foo);
    

    Will not work, because the 'this' in myObject.foo will refer to myArray instead of myObject. Instead:

    myArray.each(myObject.foo.bind(myObject))
    

    Which seems very ugly to me. That's why I usually don't program in an object-oriented way in JavaScript, but I rely heavily on closures instead.

    0 讨论(0)
  • 2020-12-13 02:00
    • It wasn't
    • Lots of OO stuff
    • It's good the way it is
    0 讨论(0)
  • 2020-12-13 02:01
    • It should be called 'self' instead
    • Anything that refers to current objects state.
    • By choosing 'self' as the name for 'this', and passing it explicitly (as the first argument) to all methods. This way you can easy tell instance method from static method or from function.

    Sorry, but I really like Python ;-)

    0 讨论(0)
提交回复
热议问题