Returning undefined on an object created by a class

Viewed 283

Why is this object created based on a class returning undefined? shouldn't it return the 'red'?

this.name='red' // global.name
class foo {
    constructor(name){
        this.name= name
        return function (){
            console.log(this.name); // new object is gonna return only this
        }
    }
}
let oof = new foo ('green');
console.log(oof) //name is not defined. Expected to return 'red' (global)
oof(); //cannot read the property
function color () {
    console.log(this.name);
}
color(); //red

thanks!

Edit1: I misswrote the oof. Corrected now.

Edit2: So guys, I know that a constructor usually don't take a return (it wouldn't make sense) and that the this keyword refers to the object that's going to be created. The thing here is that I was trying to test the limits of the this. In a normal function, this.namewould return 'red' as it's called in the global scope. Why it's not working in this case? because it's a function created by a class?

Edit3: To make it clear, I added another function color, which is supposed to be the same as oof (both are functions and called on the window) but refering the globalThis (red). The only difference is the way the are constructed.

4 Answers

There are two things going on here: Fist, you can't return that function from the constructor, you may want to set it as a property:

this.name='red' // global.name
class foo {
    constructor(name){
        this.name= name
        this.sayName = function (){
            console.log(this.name); // 
        }
    }
}
let oof = new foo ('green');
oof.sayName()

Note: on classes we usually add function as methods, not directly as a property like i just did.

The second issue is scope, you are binding the name property to the instanced object so you won't directly change global.name, but 'this.name' => oof.name instead.

Remember: when dealing with classes, 'this' will always refer to the instance object.

The this reference is not what you are expecting in your code. The rule of thumb is: "within the context of a function, this takes the value of the object effectively invoking that function".

When you do oof() there is no object invoking it, in despite you would have expected the global scope to have been passed to oof that's not the case.

If you want your code to work as you have your function defined you could try ({name:'surprise', oof}).oof(). Here you see there's an object with an attribute name invoking your function and that's the object this refers to within oof.

For more info on how this works you could take a look do MDN docs on this

1.- typo: off() seems to be oof()
2.- with the return function() {} you are going one scope ahead, so the this does not refer to the class anymore but to the returned function.

This is what you might be after:

this.name='red' // global.name
class foo {
  constructor(name){
      this.name= name
      return this.logger();
  }
  logger() {
    console.log(this.name); // 
  }
}
let oof = new foo ('green');
oof() //name is not defined. Expected to return 'red' (global)`

Ok so after 3 days of headache and thanks to the replies I think I got the solution:

    this.name='red' // global.name
    function color(){
        'use strict'
        console.log(this.name);
    }
    class Color  {
        constructor(){
            return function (){
                console.log(this.name)
            }
        }
    }
    let foo= new Color();
    let newObj= {name: 'blue',foo,color}
    newObj.color(); //blue
    newObj.foo();  // blue
Related