Bind is transient¶
Test code¶
Here’s the test code for attribute bind.
TEST('transient-bind', function()
{
// Set up the test object.
var return_this = function(){
return this;
};
var obj = {
return_this : return_this
};
assert( obj.return_this === return_this );
// Deferring method call changes the outcome.
var method_deferred = obj.return_this;
assert( method_deferred === obj.return_this );
assert( method_deferred() !== obj.return_this() ); // AAA
// The two outcomes, precisely stated.
assert( obj.return_this() === obj );
assert( method_deferred().telltail === 'global' );
// Another view on the matter.
assert( method_deferred === return_this );
assert( method_deferred() === return_this() ); // BBB
});
Discussion¶
We create an object that has a return_this method. The outcome of calling return_this depends on how it is called.
There’s a logic in the test code that produces contradictory, or at least surprising, outcomes.
From
we would expect
But this means that in obj.return_this() the obj is not relevant. But JavaScript (or its designers) wanted objects to have methods, so they introduced a special rule.
Explanation¶
JavaScript does not distinguish classes and instances. Python, and perhaps other dynamic languages, does. This allows Python to supply a bound method, which retains a reference to the object, when a function belonging to the class is called on an instance.
Here’s a Python (version 3) command line dialogue that illustrates this.
>>> def method(): pass # The function.
...
>>> class A: method = method # The class.
>>> A.method # Function from class.
<function method at 0x15be518>
>>> A.method is method # Same as the original function.
True
>>> a = A() # Instance.
>>> a.method # Bound method, not original function.
<bound method A.method of <__main__.A object at 0x16b9d10>>
The odd behaviour shown in the JavaScript test code is a consequence of JavaScript not distinguishing between classes and instances.