Interesting. I think it has something to do with scopes.
console.log(one.two.three() + "" + go());
//equals console.log(1 + "" + 3);
will output 13 (String) because:
one.two.three() returns 1
go() returns 3
- those numbers are concatenated into String with
"" (empty string) in between (instead of - as you may have asked)
Why go() returns 3
var x = 3;
// var go = one.two.three;
// equals
var go = function() {
return this.x
}
The declaration var go = one.two.three; assigns one.two's three method as a function into the variable go in the global scope. The same scope with go, one, and x (with the value 3), that was declared before declaring one and go (var x= 3;).
Based on your whole codes, this.x's this is in the global scope. and this.x is 3. So running go() returns 3.
one.two.three is a global function
→ notice there's no (), so assigning a function to global scope's variable go will make the function's scope global.
→ go function is run under global's scope
Why one.two.three() returns 1
Well, one.two.three is a method inside the object two, which is inside the object one. While the definition looks the same,
function() {
return this.x;
}
when you run three method of two object, return this.x's this refers to the method's parent object (which is two, three's parent object is two).
So,
this.x refers to
two.x which is 1.
Hence, in this case return this.x; outputs 1.
one.two.three() is 1
→ notice the () which means run the function
→ three method is run under two's scope
Addition
This will output 1-undefined because:
y is not defined in the global/one/go scope
- I use
- as a delimiter in console.log
var one = {
y:2,
two: {
y: 1,
three:function(){
return this.y;
}
}
}
var go = one.two.three;
console.log(one.two.three() + "-" + go());