Problem with declaring Javascript objects

Exploring the world of OOP for the first time, encountering a small challenge:

const panel = {    
    image : imgs[24],
    proportion : this.image.height / this.image.width,

    height : this.image.height - (scale),
    width : height / proportion,

    x : center.x - (width / 2),
    y : center.y - (height / 2)    
}

panel.draw = function(){    
   g.ctx.drawImage(this.image,
      0, 0,
      this.image.width, this.image.height,
      this.x, this.y,
      this.width, this.height)
}

Encountering a typeError issue when trying to declare this.image.height. Seeking an explanation for this.

Additionally, looking for a neater way to declare the method within the object to maintain code organization without clutter.

Answer №1

Is your element always tied to the name panel? If so,

var panel = {};
panel.img = imgs[24];
panel.prop = panel.img.height / panel.img.width;
...

If it's not always tied but you don't want multiple instances of it, create an initialization function to get the correct this

var panel = {   // assuming "scale" and "center" in scope
        init : function(){
            this.img = imgs[24];
            this.prop = this.img.height / this.img.width;
            this.h = this.img.height - (scale);
            this.w = this.h / this.prop;
            this.x = center.x - (this.w / 2);
            this.y = center.y - (this.h / 2);
        }
};
panel.init();
...

If you want to have multiple instances of the object, create a constructor

function Panel (img) { // assuming "scale" and "center" in scope
    this.img = img;
    this.prop = img.height / img.width;
    this.h = img.height - (scale);
    this.w = this.h / this.prop;
    this.x = center.x - (this.w / 2);
    this.y = center.y - (this.h / 2);
}
Panel..draw = function(){
...

and use with

var panel = new Panel( imgs[24] );

Answer №2

When utilizing object literal syntax, this will not be referencing the object being created. Instead, it will reference the outer variable scope.

To effectively use literal syntax, begin by creating the parts that do not rely on a self reference. Then, proceed with creating the remaining parts after initialization.

var panel = {    
    img : imgs[24],

    w : h/prop,

    x : center.x - (w / 2),
    y : center.y - (h / 2)    
};
panel.prop = panel.img.height / panel.img.width;
panel.h = panel.img.height - scale;

The identity of h and prop variables is unclear. Are they supposed to refer to object members? Also, the origin of the center variable seems ambiguous.

Perhaps there is some uncertainty surrounding JavaScript syntax understanding. It could be beneficial to explore a foundational tutorial before proceeding further.

Answer №3

Even though you might believe otherwise, you are actually referencing a different object. In your scenario, when you use this on the third line, it is referring to the current scope and not the panel object you are creating. Therefore, references like img and h are different.

var panel = {    
    img : imgs[24],
    prop : this.img.height / this.img.width, // this does not refer to panel here

    h : this.img.height - (scale), // this.img is not the same as panel.img
    w : h/prop, // h is not equal to panel.h

    x : center.x - (w / 2), // w does not equal panel.w
    y : center.y - (h / 2)  // h is not equal to panel.h  
}

panel.draw = function(){    
   g.ctx.drawImage(this.img,
      0, 0,
      this.img.width, this.img.height,
      this.x, this.y,
      this.w, this.h)
}

A better approach would be something like this:

var Panel = (function() {    
    function Panel(img, scale, center) {  
       this.img = img
       this.prop = img.height / img.width
       this.h = img.height - scale
       this.w = this.h/this.prop
       this.x = center.x - (this.w / 2),
       this.y = center.y - (this.h / 2)
    }
    Panel.prototype.draw = function(ctx) {
          ctx.drawImage(this.img, 0, 0,
          this.img.width, this.img.height,
          this.x, this.y,this.w, this.h)
    }          
})():

var panel = new Panel(imgs[24], scale, center);
panel.draw(g.ctx);

Answer №4

this pertains to the specific environment in which panel is defined, rather than the panel object itself. Here are a few ways to address this issue :

1. Store the referenced object in a cache :

var img = imgs[24];
var panel = {
    img: img
  , height: img.height - scale
  , //...

2. Create an empty panel object and gradually add properties :

var panel = {};
panel.img = imgs[24]
panel.height = panel.img - scale;

3. Functions can be declared like any other property.

var panel = {
    img: imgs[24]
  , draw: function(){ g.ctx.drawImage(this.img, 0, 0) }
}

Answer №5

The panel object does not include the panel.img.height property.

var panel = {    
    img :
        { height: // add content here
        }
    prop : this.img.height / this.img.width,

    h : this.img.height - (scale),
    w : h/prop,

    x : center.x - (w / 2),
    y : center.y - (h / 2)    
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Cloning a table row through editing functionality in ReactJS

Hey there, I'm currently working on implementing an edit feature in react.js. The current functionality is such that when the edit button is clicked, it displays the row data in the name and email address fields. If submitted without any changes, it c ...

Redirecting with React Router outside of a route component

I am using React Router in my application to manage the routing functionalities. However, I have encountered an issue where I need to redirect the user from the Header component, which is not nested inside the Router component. As a result, I am unable t ...

How does Backbone.js tackle error handling when receiving messages from Rails?

Can anyone using backbone.js lend a hand? How can error messages from a rails app be encoded when integrating with backbone.js? For instance, how should flash messages like "record not found" be handled? While errors are usually defined on the client sid ...

A guide on looping through an array enclosed within an object with the help of ng-repeat

I am trying to retrieve data from an API endpoint that returns a single object. Within this object, there is an array called video which I want to iterate over and display all the links stored in the array on the view. The JSON object returned by the API: ...

The JavaScript slideshow fails to display an image during one rotation

The slideshow displays a sequence of images from pic1.jpg to pic8.jpg, followed by a 4-second pause with no image, and then repeats starting again at pic1.jpg. I am looking to have it loop back to pic1.jpg immediately after displaying pic8.jpg. Below is t ...

Menu options submerged beneath the surface of a concealed container with overflow property

Attempting to enhance the ui-grid by adding more options to each row using the "3 dots" approach. However, encountered an issue where the dropdown menu extends beyond the screen due to the use of position: absolute. Unable to switch to position: relative b ...

Having trouble with the functionality of a simple jQuery toggle menu on mobile?

I am experiencing an issue with a simple toggle menu that utilizes jQuery's on: tap feature, but it is not functioning as expected: <nav id="mobile-nav"> <ul> <li>Item 1</li> <li>Item 2</li> ...

Where will the user's input be stored?

Consider the following HTML code: <div class="form-group"> <label class="col-md-3 col-xs-3 col-sm-3 control-label">Phone</label> <div class="col-md-4 col-xs-4 col-sm-4"> <input id="input ...

Refining an array with React's filter method

Currently, I am in the process of creating a To-Do Application using React. However, I have encountered a roadblock along the way. My struggle lies in mapping through items within an array and presenting them in an unordered list. I am attempting to util ...

Guide for animating individual mapped elements in react-native?

After mapping an object array to create tag elements with details, I added an animation for the tags to zoom in on render. However, I wanted to take it further and animate each tag individually, sequentially one after the other. This appears to be a common ...

Attempting to instruct my chrome extension to execute a click action on a specific element found within the webpage

I am currently working on developing a unique chrome extension that has the capability to download mp3s specifically from hiphopdx. I have discovered a potential solution, where once the play button on the website is clicked, it becomes possible to extract ...

Steps to properly create your own angular service with XHR

Exploring the world of AngularJS, I embarked on a mission to create a file upload feature along with other form data. While there are numerous scripts and plugins available, I decided to utilize my own custom service using $xhr. Despite successfully sendin ...

An array in Javascript that contains sub-arrays within its keys

I am encountering an issue with my array structure. The main array contains sub-arrays and uses custom keys as identifiers. However, I am unable to access the array using these keys. For example, when I try to get the length of the array, it returns 0 even ...

Consolidate two AJAX requests into a single callback

I'm developing a Chrome extension and facing the challenge of merging two separate AJAX calls into one callback upon success. What would be the most efficient approach to achieve this? Auth.prototype.updateContact = function(id, contact_obj) { var ...

How to incorporate an icon into a React Bootstrap Dropdown menu

I'm struggling to figure out how to include an icon in my react dropdown button, similar to the one shown in the following example. https://i.sstatic.net/cn0b0.png The react bootstrap package I am currently using does not seem to offer a straightfor ...

What is a common mistake when using refs in React?

I've recently started diving into React. I've seen conflicting opinions on using refs - some sources claim it's a bad practice altogether. Can someone clarify this for me? Is it harmful to attach refs to child components in order to access ...

Is there a way to break this down so that I can obtain an array containing the data for each month?

My JSON structure is as follows: "meterConsumption": [ { "month": 1, "details": [ { "timestamp": "2020-01-01", ...

Breaking apart a string and mapping it to specific fields

My issue is relatively straightforward. Upon loading my page, a long string representing an address is generated. For example: 101, Dalmations Avenue, Miami, Florida, USA, 908343 With the help of jQuery, I can split the string using: var address = sel.o ...

What steps can be taken to add a radio button group to a form in order to choose between the smoking and non-smoking sections of a restaurant?

I'm trying to replicate the functionality of radio buttons within a bootstrap form-group, where a line in a form contains multiple buttons ("btn btn-success" for example) that can be selected, but only one at a time. I am aiming for an output like thi ...

The unique format created by tinyMce is not being displayed

I am trying to customize the style format of my tinyMCE, but I am having trouble getting it to show up. Can anyone suggest what might be going wrong? Where should I place the button "Formats" so that I can choose a specific style? tinyMCE.init({ mod ...