[SOLVED] JavaScript Confusion

Sorry idk where to post this. I am unmedicated, two red bulls into the night, and I have not used JavaScript in a while, but wanted to do some number crunching. I cannot fathom what I’m doing wrong.

Here’s the fundamental setup:

var myObjectA = {
    objectArray: [],
    objectMethod: () => {
        this.objectArray.push(64);
        this.objectArray.push(128);
        console.log(this.objectArray.length); // says "2"!
    }
};

myObjectA.objectMethod();

var myObjectB = {
    checkVal: 1,
    checkMethod: () => {
        console.log(myObjectA.objectArray.length); // says "0"?!
        if (myObjectA.objectArray.length === this.checkVal) {
            console.log('Match!');
        }
    }
};

myObjectB.checkMethod();

The error I’m getting is myObjectA.objectArray.length is 0.

Am I having a stroke right now??? Did I forget some absolutely fundamental part of JavaScript since I started doing a lot of work in TADS 3?!

This is literally the setup. All the help online is talking about async issues, but I’m not using any of that here. Just simple, step-by-step calculation. I absolutely do not understand why the array seems to fill, and then is randomly empty when the second method runs.

Any help or guidance is appreciated, thank you.

1 Like

I don’t know JS, but is this line correct? Seems like it should read

myObjectA.ObjectMethod();
2 Likes

Good catch; let me update the spelling! :joy: Everything is spelled correctly in the actual code that I’m working on. I just misspelled it for this simplified example.

2 Likes
var myObjectA = {
    objectArray: [],
    objectMethod: function() {
        this.objectArray.push(64);
        this.objectArray.push(128);
        console.log(this.objectArray.length); // says "2"!
    }
};

myObjectA.objectMethod();

var myObjectB = {
    checkVal: 1,
    checkMethod: function() {
        console.log(myObjectA.objectArray.length); // says "2"!
        if (myObjectA.objectArray.length === this.checkVal) {
            console.log('Match!');
        }
    }
};

myObjectB.checkMethod();

Just changed the way the function () was being created and it seems to work.

2 Likes

I think this is the problem. if you change
objectMethod: () => {
to
objectMethod() {
in the definition of myObjectA it seems to work.

(But I’m no expert in JavaScript, doubtless there’s a better answer.)

Jeremy

3 Likes

That works too. The thing I don’t understand is how Joey was getting the first console log to output. My browser was putting out errors before that could even happen. I’m not a JS guru though.

3 Likes

Yes, I got undefined on objectArray as well.

2 Likes

If running the original code in a browser (Chrome), this will refer to window, not myObjectA and as you say throws an error.

3 Likes

function objectMethod() { …, I assume? But yeah, “Arrow functions don’t have their own bindings to this, arguments, or super, and should not be used as methods.”

And since this is simplified example code, I’m assuming that one or both of those arrow functions were picking up a this from somewhere that did happen to have an objectArray property? But not the same ones as each other? Because arrow functions don’t clear this, they just don’t have their own. It just acts like a normal variable, so they can pick up a this from the context where they’re defined (“close over this”). At least I’m pretty sure that’s how it works.

3 Likes

It can be pretty confusing. Later the MDN article says they’re also called “auto-bound methods”. That seems clearer to me, because to get a normal function to always have a specific this you have to call bind().

Arrow functions have the this of the context they’re defined in, which in this case is the global, not the object they’re a part of. Whereas a normal function is unbound and takes whatever is before the . as its this.

3 Likes

Lambdas and functions are not equivalent. I encountered the same problem recently trying to do my_lambda.call(object, args). I think the rationale is that lambdas are a shortcut and writing let self=this is too much trouble.

1 Like

In other languages lambdas can be quite different from other functions, but in JS they’re basically the same (indeed, JS doesn’t use the term “lambda”.) Arrow functions just auto-bind the this, so it can’t be changed by call(). But if you’re only using them in situations in which you want to auto-bind the this then there shouldn’t be issues…

2 Likes

Oh my gawd I apparently forgot that functions in object definitions are not not required to be in lambda format.

I really appreciate everyone chipping in!! :grin: I understand clearly now!

EDIT: More specifically: My assumption was that methodName() { ... } format was only valid for class definitions, and that anything in an object definition like objName = { propA: 6, propB: 'apples' }; needed to have functions written in methodName: () => { ... } format. However, I am very mistaken, lol.

I’ve learned a lot!!

4 Likes

I would sure hope that it wasn’t the case, because I don’t undorstand arrow functions and just name everything lol

1 Like

You can also use the “old” style:

var obj = {
  method: function () {
  }
}

method() {} inside an object is only a shortcut but is equivalent.

In JS, the term “lambda” is not often used but when it is, it is to refer to all anonymous functions (not only arrow functions but also traditional functions without a name).
When you say “in lambda format”, I believe you mean “arrow function”.

1 Like