1

am a beginner learning javascript and was playing around with Objects and am wondering why this code is throwing an error.

var a =  {
    greeting: "Hello",
    greet: this.greeting +  "John"
}
console.log(a.greet);
  • 2
    It is throwing an error because when you are initializing an object, you cannot reference other fields in that object. – tomerpacific Dec 18 '18 at 15:15
  • You cannot use 'this' inside the object creation, a JSON object doesn't exist at this stage. Also, member names should be encapsulated in quotes. Try one of the many online JSON validators. – SPlatten Dec 18 '18 at 15:16
  • The above code is not throwing an error, it's rather logging `undefinedJohn`, because the `this` you are using does not refer to `a`, but to `window`. – briosheje Dec 18 '18 at 15:16
  • 1
    It does not trow an error. It just returns undefined for `this.greeting` because this is not defined in the global scope. – Mark Baijens Dec 18 '18 at 15:16
  • @briosheje it would throw an error in strict mode inside a function. – VLAZ Dec 18 '18 at 15:16
  • @vlaz there is no strict mode in the example provided by the OP though. It's just not throwing an error in that scenario specifically, is it? – briosheje Dec 18 '18 at 15:17
  • See here https://stackoverflow.com/questions/7043509/this-inside-object and here https://stackoverflow.com/questions/4616202/self-references-in-object-literals-initializers – lakewooddev Dec 18 '18 at 15:21
  • @briosheje OP says they are a novice in JS. I'd cut them some slack in not expanding on the, frankly, a bit obscure and obtuse strict mode. Which they probably don't really know about at all. – VLAZ Dec 18 '18 at 15:22

3 Answers3

1

While it's been clarified why your code throws an error, I wanted to explain how you could have it instead.

Javascript makes no difference between ordinary functions and constructors, to a class is just a call to new function with any function in front of it.

Therefore, a way the object can reference itself is by using a function body as its definition:

const AClass = function () {
  this.greeting = 'Hello'
  this.greet = this.greeting + ' John'
}

const a = new AClass()
console.log(a.greet)

Shorthand since you aren't going to create more than one AClass object (at least in your example):

const a = new function () {
  this.greeting = 'Hello'
  this.greet = this.greeting + ' John'
}()

console.log(a.greet)
gchiconi
  • 624
  • 1
  • 7
  • 17
1

Yours doesn't work because of the problems described in the comments.

I'm guessing that you want something like this:

var a =  {
    greeting: "Hello",
    greet: function() {return this.greeting +  " John"}
}
console.log(a.greet());

Or like this:

var a = (() => {
    var greeting = "Hello"
    return {
        greeting,
        greet: greeting + ' John'
    }
})()

console.log(a.greet);

The first one makes greet a function, which means that it will respond to later changes in greeting. The second one creates an object based on the greeting value. But you have to use a local variable for the reference, since your this at the time of construction is not the new object but some outer scope, possibly something like window.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
-1

This question you have is explained here: How Do I reference objects proerty at creation

In order to do what you want you can use an object getter.

 var b = {
        greeting: "Hello",
        get greet() { //this a getter that accesses greeting
            return this.greeting + " John";
        }
    }
    console.log(b.greet);
L0uis
  • 703
  • 5
  • 8
  • While it passes the test and is probably better for a reactive `greeting` property, it does not behave exactly like the proposed code should. One such example is when calling `JSON.stringify` with this object. – gchiconi Dec 18 '18 at 15:28