Why is assigning a function object returning a empty string

Viewed 60

So I am trying to learn functional programming and I see that when I return

const profile = {
  name: 'qw',
  children: [{
    name: 'peter',
    getName() {
      return this.name;
    }
  }],
  getName() {
    return this.name;
  }
};
const val = profile.getName();

console.log(`output is ${val}`); //I get 'qw' as expected


//However if I try 

const val1 = profile.getName;
console.log(`output is ${val1()}`); //I get ''

I am not sure why this is returning different things on not using '()'

2 Answers

Adding to @VLAZ's comment, const val = profile.getName(); returns the result of the invocation (this is within the profile context) while const val = profile.getName; just references getName in profile.When you do invoke it, then the context is window.

In other words profile.getName() executes (using the correct this) while profile.getName does not execute. And when it does, the context is window

const profile = {
    name: 'qw',
    children: [
        {
            name: 'peter',
            getName() {
                return this.name;
            }
        }
    ],
    getName() {
        return this.name;
    }
};
const val = profile.getName();
// this is the equivalence of "qw" which is the result of invoking `getName`

console.log(`output is ${val}`); // 'qw'

const val = profile.getName;
// this is the equivalence of:

  getName() {
     return this.name;
   }
// And the context here is the window.   
console.log(`output is ${val}`); // ''

Despite the short syntax, getName() is still just a regular function, which happens to be stored in an object. It does not carry an object reference around, this is evaluated when/where/how you call it:

var obj1={
  test:"This is obj1",
  logTest(){console.log(this.test);}
};

obj1.logTest();

var fun=obj1.logTest;
fun();
var test="This is window";      // in browsers, regular variables on the top-level
fun();
window["test"]="Indeed it is";  // are actually members of window
fun();
this.test="All the same";       // really they are
fun();

var obj2={
  test:"This is obj2",
  testfun:fun
};
obj2.testfun();

//////////////////////////////////////
console.log("--------");

var boundfun=obj1.logTest.bind(obj1);
boundfun();

var obj3={
  test:"This is obj3",
  testfun:boundfun
};
obj3.testfun();

However the last part, boundfun(), shows a method of function objects, bind() which you can use to "pre-parametrize" a function, where the first parameter you can set is the this. I also suggest checking the other two methods linked on the left side of that page, call() and apply(), both are about invoking a function via not just passing its arguments, but also freely setting this. So you could create your own bindthis() if you wanted to:

var obj1={
  test:"This is obj1",
  logTest(){console.log(this.test);}
};

function bindthis(fun,diz){
  return function(){
    fun.call(diz);
  }
}

var boundfun=bindthis(obj1.logTest,obj1);

boundfun();

var obj2={
  test:"This is obj2",
  testfun:boundfun
};

obj2.testfun();

Side note: the question is not really about functional programming, this is an object-oriented concept. So what you see is more like one particular mix of functional and object-oriented programming.

Related