actually your code is wrong because your snippet doesnt run, you should be doing the following: console.log( this.a );
and now, lets see how this works.
function foo() {
console.log( this.a );
}
this will call this
in the scope of the caller, so lets investigate our results.
so, you are setting a=2
globally, and then in the objects o.a = 3
and p.a=4
so:
calling o.foo
it will return 3
because this is pointing to o
calling p.foo
it will return 4
because this is pointing to p
BUT
calling (p.foo = o.foo)();
it will return 2
because it is not pointing to any object, so it will take your scope (which is the global scope) and then it will return 2
.
if you go with:
p.foo = o.foo
p.foo() //4
it will return 4 successfully because it is pointing to p
.