"Why is JavaScript confused,"
It's not. It has a specific set of rules governing how access to object properties works. It's just that those rules are not the same as every other OO language.
"in many other OO languages this
is used only to make code explicit to the reader"
In some OO languages, e.g., Java, this
is sometimes used just to make the code explicit to the reader, but really it isn't completely optional - it is required to distinguish between instance variables (members) and other variables of the same name (e.g., local variables in methods).
JavaScript is object oriented, but it doesn't have classes and doesn't have member methods like some other OO languages such as Java. In JavaScript functions are a type of object and in general terms any variable or object property may be set to reference any function - so even when you define a function inside an object literal like in the question that function isn't owned by the object in question. An example:
function test1() {
alert('test1');
}
var obj1 = {
prop1 : 'obj1',
method1 : test1,
method2 : function() {
alert(this.prop1);
}
}
var test2 = obj1.method2;
obj1.method1(); // alerts 'test1'
test1(); // alerts 'test1'
obj1.method2(); // alerts 'obj1'
test2(); // alerts undefined (probably; see note below)
test2.call({prop1 : 'test2'}); // alerts 'test2'
delete obj1.method2; // remove the property
alert(obj1.method2); // alerts undefined - property no longer exists
test2.call({prop1 : 'test2'}); // alerts 'test2' - the function still exists
Notice that obj1.method1
references a function defined outside the literal, a function that can be called directly with test1()
. Similarly, test2
has been set to refer to a function that has been defined in the literal but can be called directly - even if you actually remove the method2
property you can still call test2()
directly.
I defined method2
/ test2
so that it uses this.prop1
. The value of this
is set depending on how a function is called. If you call it with "dot" notation, like obj1.method2()
then within the function this
will be the object before the dot. If you call the function directly like test2()
then in non-strict mode this
would be window
, but in strict mode may be undefined or some other value - see MDN for more details. Or you can call a function with .call()
or .apply()
and explicitly set this
to some other object, like in the example above.