objectthis

In applying bind() on an object, does Function Bound signify Error?


I have been using the this keyword for quite a while now but it has raised my curiousness to know much about it. I did a research and I came across a lengthy lessons and examples on the W3school site (https://www.w3schools.com/js/js_this.asp). Methods like call(), apply(), and bind() can refers the this keyword to any object. I declared few objects and called the call() and apply() methods on them, and I got exactly the output I was expecting to see in the console. In the below exercise, I declared two different objects with the first object(studentOne) containing a function. Using the bind() method; I have tried to borrow a method from the first Object(studentOne), in order to use it in the second object(studentTwo) and get the student full Name printed out in the console, but I keeps getting [Function: bound fullName] and undefined(when JSON.stringify() is apply). Can some please explain this behavior properly for me?

const studentOne = {
    givenName: 'Wolubah',
    nickName: 'Gissi King',
    familyName: 'Timibah',
    sex: 'Male',
    age: 45, 
    fullName: function() {
        return this.givenName + ' ' + this.nickName + ' ' + this.familyName;
    }
};


const studentTwo = {
    givenName: 'Weddor', 
    nickName: 'Sugar',
    familyName: 'Tamba',
    sex: 'Female',
    age: 34
};

const bindName = studentOne.fullName.bind(studentTwo);
console.log(bindName);//[Function: bound fullName]

console.log(JSON.stringify(bindName));//undefined 

//call() method on object

const objOne = {
    thisPerson: function() {
        return this.givenName + ' ' + this.middleName + ' ' + this.familyName; 
    }
};

const objTwo = {
    givenName: 'Hawalyn',
    middleName: 'Kamaralyn',
    familyName: 'Kamara',
    sex: 'Female',
    age: 7
};


const childName = JSON.stringify(objOne.thisPerson.call(objTwo));
console.log(childName);// "Hawalyn Kamaralyn Kamara"

Solution

  • When you bind() a function, you are creating a new function object that will call the bound function with this set as the object that was passed to bind().

    This is useful because, passing around functions (as first-class objects) has a potentially confusing behaviour. Especially when compared to other programming languages that have first-class functions. Basically, this is set to context that the function was called from. Not the object it was defined on. ie.

    name = 'global value';
    
    const person = {
      name: 'member value',
      getName: function() {
        return this.name;
      }
    };
    
    console.log(person.getName()); // prints "member value"
    // functions as first class objects
    const getNameUnbound = person.getName;
    console.log(getNameUnbound());  // prints "global value"
    const getNameBound = person.getName.bind(person);
    console.log(getNameBound()); // prints "member value"
    

    In the above example, when I did const getNameUnbound = person.getName I moved the function into the global (window) scope, so now when I call getNameUnbound, this is set to the window/global object, and not the person object.

    This works for any object as well.

    const personTwo = {
       name: 'person two',
    };
    
    personTwo.getName = person.getName;
    
    console.log(personTwo.getName()); // prints "person two"