Alexandru Popescu
Alexandru Popescu

Reputation: 67

How to make an object constructor in JavaScript;

Could you please explain me what's wrong in the following code?

function box (width, height, color) {
    this.width=width;
    this.height=height;
    this.color=color;
    this.style.width=width;
    this.style.height=height;
    this.style.backgroundColor=color;
}

var box1 = new box (100, 100, 'red');

document.body.appendChild(box1);

Upvotes: 5

Views: 301

Answers (3)

KooiInc
KooiInc

Reputation: 122888

This is not a constructor, but just a function. this in the function is not an element.

Within the function you are not creating the actual box. Some properties (e.g. this.color) will be assigned but will not always do what you expect. Furthermore the function box returns nothing, so there's nothing to append.

Here's a skeleton to create an element, but I suggest you to first try learning more JS/Html/Dom scripting.

function box (width, height, color, backgroundColor) {
  const box = document.createElement("div");
  const toPx = n => `${n}px`;
  box.style.width = toPx(width);
  box.style.height = toPx(height);
  box.style.color = color;
  box.style.backgroundColor = backgroundColor;
  // return this, otherwise there's nothing to append
  return box;
}

var box1 = box(100, 100, 'white', 'red');
box1.textContent = "Hello world";
document.body.appendChild(box1);

Upvotes: 0

Majed Badawi
Majed Badawi

Reputation: 28404

You need to createElement and pass it the parameters as follows:

function box (width, height, color) {
  this.element = document.createElement('div');
  this.element.style.width=width+'px';
  this.element.style.height=height+'px';
  this.element.style.backgroundColor=color;
  return this.element;
}

var box1 = box (100, 100, 'red');

document.body.appendChild(box1);

Upvotes: 4

T.J. Crowder
T.J. Crowder

Reputation: 1073968

The main problem is that box doesn't create a DOM element. You can't just append any object to the DOM, it has to be a DOM node of some kind (element, text node, etc.).

If you did have box create a DOM element, you wouldn't want to store width, height, and color on it directly, just in its style object.

Since the object created when you use new will get thrown away, I'd use createBox instead and not use new with it:

function createBox(width, height, backgroundColor) {
    const element = document.createElement("div");
    element.style.width = width + "px";
    element.style.height = height + "px";
    element.style.backgroundColor = backgroundColor;
    return element;
}

document.body.appendChild(
    createBox(100, 100, "red")
);


If you weren't wanting to create a DOM element, then the problem with this.style.width=width is that it's trying to assign to undefined, because this doesn't have a style property, so this.style is undefined. If you want to create an object from various properties, you can use an object literal:

function Box(width, height, color) {
    this.width = width;
    this.height = height;
    this.color = color;
    this.style = {width, height, backgroundColor: color};
}

(Note that I changed box to Box. The overwhelming convention in JavaScript is that constructor functions (ones you call via new or similar) start with an uppercase character.)

But if you're creating a DOM element instead, it'll have a style object already.

I should note that I've used shorthand properties for width and height there, which were added in ES2015 and so nearly universally supported, but not by obsolete browsers like IE11. If you need to support them, use the long form instead (width: width).

You might also look in to ES2015's class syntax, which lets you create constructor functions and fill in the object they assign as the prototype of instances in a more concise, less error-prone way. If you need to target ES5-only browsers, there are tools like Babel to transpile for you.

Upvotes: 2

Related Questions