-1

Hi In the example below I am importing MeasurementObject using: import MeasurementObject from './app/..etc'

When I call an instance of MeasurementObject.getScrollToValue()

The this inside the method MeasurementObject.getScrollToValue() refers to the executing context. As a result this.getURL() is undefined. How can I get it to to refer to the current context of MeasurementObject and hence call this.getURL().

const  MeasurementObject  = {

    getType(){
        return "a"
    }

    getURL(){
        return "b";
    }

    getScrollToValue(){
        return this.getURL();
    }
}

export default MeasurementObject;
Shivam Sinha
  • 4,924
  • 7
  • 43
  • 65
  • 1
    Are you asking the difference between a javascript object literal and a function or a class? – Robert Moskal May 23 '16 at 01:15
  • 3
    You've edited your question to a completely different question. Thanks for wasting everyone's time. – Mulan May 23 '16 at 01:25
  • 1
    You seem have completely changed your question. When you call the function with `MeasurementObject.getScrollToValue()`, `this` inside the method will refer to `MeasurementObject`, so what you have works fine. Not sure what you mean with *"The `this` inside the method ... refers to the executing context"*. – Felix Kling May 23 '16 at 01:25
  • @naomik apologies ... I thought i knew what was causing the problem was and hence got more specific with the question. – Shivam Sinha May 23 '16 at 01:29
  • 1
    And your question is still wrong .. because if you call `MeasurementObject.getScrollToValue()` this will refer to the MeasurementObject context you just didnt return it and therefore got undefined – Neta Meta May 23 '16 at 01:30
  • Default-exporting singleton module-objects is an antipattern in ES6. Use named exports instead - and your `this` context issues are solved as well. – Bergi May 23 '16 at 01:32
  • https://babeljs.io/repl/#?evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&code=const%20%20MeasurementObject%20%20%3D%20%7B%0D%0A%0D%0A%20%20%20%20getType()%7B%0D%0A%20%20%20%20%20%20return%20%22a%22%0D%0A%20%20%20%20%7D%2C%0D%0A%0D%0A%20%20%20%20getURL()%7B%0D%0A%20%20%20%20%20%20return%20%22b%22%3B%0D%0A%20%20%20%20%7D%2C%0D%0A%0D%0A%20%20%20%20getScrollToValue()%7B%0D%0A%20%20%20%20%20%20console.log(this)%3B%0D%0A%20%20%20%20%20%20return%20this.getURL()%3B%0D%0A%20%20%20%20%7D%2C%0D%0A%7D%0D%0A%0D%0Aconsole.log(MeasurementObject.getScrollToValue())%3B – Neta Meta May 23 '16 at 01:32
  • @FelixKling "The this inside the method ... refers to the executing context" what I mean is ...it seems `this` varies depending where I call the method from if I call it from one of the react native lifecycle hooks is refers to the global context. However if I call it from a non lifecycle function `this` refers to the current object and works as expected. – Shivam Sinha May 23 '16 at 01:32
  • @ShivamSinha i think you are assigning the function to another variable or another object and you then trying to execute it therefore losing context - which is a different issue completely. to resolve you'll have to rebind the context. – Neta Meta May 23 '16 at 01:34
  • @NetaMeta thanks you are right I was losing the context – Shivam Sinha May 23 '16 at 01:42
  • More context / real code next time might have save you 2 downvotes and people's time. either way good luck and read my answer it might shade some light on classes for you – Neta Meta May 23 '16 at 01:43
  • *"it seems this varies depending where I call the method from"* The value of `this` only depends on **how** a function is a called (and whether it is bound or not). This is possibly a duplicate of [How to access the correct `this` / context inside a callback?](http://stackoverflow.com/q/20279484/218196) – Felix Kling May 23 '16 at 01:46

2 Answers2

2

The fact that you're exporting them makes no difference.

MeasurementClass is a constructor function with 3 methods defined on the MeasurementClass.prototype. getType, getURL and getScrollToValue

For you to use the class, you would have to instantiate the class using the new keyword. (new MeasurementClass()).methodName(...)

vs.

MeasurementObject is an object literal with 3 methods defined directly on the object. getType, getURL and getScrollToValue

Using the object is just a matter of calling obj.methodName()

Mulan
  • 129,518
  • 31
  • 228
  • 259
  • aside: you don't need those extra wrapping parens to use constructor results, `new MeasurementClass().methodName()` works the same. – dandavis May 23 '16 at 02:11
1

when you export a class without instantiate it, all the properties you define are set on the prototype. and you dont have a context, you need to instantiate and you then are able to use "this".

Now as for your example the "this" inside your function referring to the object correctly however you are not returning it.

const MeasurementObject = {

    getType(){
        return "a"
    },

    getURL(){
        return "b";
    },

    getScrollToValue(){
        return this.getURL();
    }
}


var a = MeasurementObject.getScrollToValue()
console.log(a)

When you define an object like that your already working on an instance and the properties are set on the object not its prototype.

update

When you do this:

class MeasurementClass {

    getType(){
        return "a"
    },

    getURL(){
        return "b";
    },

    getScrollToValue(){
        return this.getURL();
    }
}

what you get is something like:

function MeasurementClass(){}
MeasurementClass.prototype.getType = function(){ return "a" }
MeasurementClass.prototype.getURL = function(){ return "b"; }
MeasurementClass.prototype.getScrollToValue = function(){ return     this.getURL(); }

And then when you try accessing it without instantiating MeasurementClass.getScrollToValue

You are trying to access something that doesn't exist.

However when you instantiate the function all of those prototype properties are inherited to the instance so:

const measurementClass = new MeasurementClass();

measurementClass will be an instance of MeasurementClass and will inherit all its prototype.

Hope that helps a little.

Neta Meta
  • 4,001
  • 9
  • 42
  • 67
  • You seem to confuse `class` with `const`. No, object literals don't create classes with prototype objects. – Bergi May 23 '16 at 01:34
  • Bergi object litteral -- you came here way to late his initial question was related to class but thanks for your reason free downvote. – Neta Meta May 23 '16 at 01:35
  • Ah, I didn't see that horrible change of the question. Still, your answer had it wrong, thanks for the edit :-) – Bergi May 23 '16 at 01:37