Joel Almeida
Joel Almeida

Reputation: 8037

Defining an object property value based on other property

When executing the following code I get this error:

Uncaught TypeError: Cannot read property 'theTests' of undefined

$(document).ready(function() {

  var Example = {};

  Example = {
    settings: {
      theTests: $('.test'),
      firstTest: Example.settings.theTests[0]
    }
  }
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>

But if I do it this way:

$(document).ready(function() {
  var Example = {};

  Example = {
    settings: {
      theTests: $('.test'),
      firstTest: $('.test')[0]
    },
    test: function() {
      var theTests = $('.test'),
        firstTest = theTests[0]
    }
  }

  Example.test();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>
<div class="test"></div>

Defining it inside the settings, or in the function, both of them work this way.

So my question is:

Why when defining the firstTest property based on the theTests property inside the settings doesn't work?

Edit:

Like suggested by duplicate I checked this question but I'm not looking for a way to do it. I'm trying to understand why it doesn't work.

Upvotes: 1

Views: 79

Answers (5)

user757095
user757095

Reputation:

you are trying to access a variable property that is not defined in that specific time.

Example.settings will be available AFTER the Example initalization.

var Example = {};
var theTests = $('.test');

Example = {
  settings: {
    theTests: theTests,
    firstTest: theTests[0]
  }
}

the second line of this code will:

  1. create the object
  2. assign the object to the variable

Upvotes: 0

James Thorpe
James Thorpe

Reputation: 32202

I agree - it's not entirely a duplicate, since you're asking why - not how.

The reason you can't do this is given in the error - the object you're referring to isn't yet defined. Whilst you've assigned an empty object to Example, you're then immediately trying to set it to something else. Note that this is going to get evaluated from the innermost items first, ie it will be doing:

  • Set Example to be the result of:
    • Create an object that contains:
      • A settings property, which is the result of:
        • Create an object with two properties:
          • theTests: set to $(.test)
          • firstTest: set to Example.settings.theTests[0]

In the last line, note that we haven't yet assigned the settings object (we're still defining the properties on the object that will be assigned to settings), so it's undefined at the point when that line runs.

Upvotes: 2

Try:

var Example = new function(){
    this.settings = {theTests:  $('.test')};
    this.settings.firstTest = this.settings.theTests[0];

    this.test = function(){
        console.log(this.settings.theTests);
        console.log(this.settings.firstTest)
    };
};

Example.test();

Upvotes: 0

hooda
hooda

Reputation: 105

In the first sample you are trying to access a property of Example before Example has fully been initialized.

You could do something along these lines instead

$(document).ready(function() {
  var tests = $('.test');
  var Example =  {
    settings: {
      theTests: tests,
      firstTest: tests[0]
    },
    test: function() {
      var theTests = $('.test'),
        firstTest = theTests[0]
    }
  }

  Example.test();
});

Upvotes: 0

Himanshu Tanwar
Himanshu Tanwar

Reputation: 906

 var Example = {};

  Example = {
    settings: {
      theTests: $('.test'),
      firstTest: Example.settings.theTests[0] //theTests does not exist
    }
  }




 Example = {
    settings: {
      theTests: $('.test'),
      firstTest: $('.test')[0]
    },
    test: function() {
      var theTests = $('.test'), // theTests has been defined
        firstTest = theTests[0]  // and used here
    }
  }

Upvotes: -1

Related Questions