guest
guest

Reputation: 2224

prototype function not defined

The following code runs fine:

function Button(tagName) {
  var button;
  if (tagName) button = document.createElement(tagName);
  else button = document.createElement(div);

  button.innerHTML = 'Track Order';
  button.applyJsonProperties = function(jsonProperties){
    if(jsonProperties){
      for(var cssAttribute in jsonProperties){
        this.style[cssAttribute] = jsonProperties[cssAttribute];
      }
    }
  }
  return button;
}

The following code produces an error

function Button(tagName) {
  var button;
  if (tagName) button = document.createElement(tagName);
  else button = document.createElement(div);

  button.innerHTML = 'Track Order';

  return button;
}
Button.prototype.applyJsonProperties = function(jsonProperties){
   if(jsonProperties){
     for(var cssAttribute in jsonProperties){
       this.style[cssAttribute] = jsonProperties[cssAttribute];
     }
   }
}

var divButton = new Button('div');
var props = { "color" : "blue" }
divButton.applyJsonProperties(props); //returns undefined function

Upvotes: 1

Views: 2256

Answers (4)

RobG
RobG

Reputation: 147403

When a function is called as a constructor, its this is initialised as a new Object that inherits from the constructor's prototype, i.e. the object's internal [[Prototype]] references the constructor's public prototype property.

When you return a different object (in the OP, a DOM HTMLButtonElement), then that object doesn't inherit from the constructor. e.g.

function Button(tagName) {
  var button = document.createElement(tagName || 'button');
  return button;
}

Button.prototype.applyJsonProperties = function(jsonProperties){};

var button = new Button();

console.log('button instanceof Button?: ' + (button instanceof Button)); // false
console.log('button.constructor: ' + button.constructor); // Not Button
console.log('Typeof button: ' + typeof button); // object
console.log('Typeof button.applyJsonProperties: ' + typeof button.applyJsonProperties); // undefined

As Rudolf Manusadzhyan suggests, you can have the element as a property of the instance and call methods on that, e.g.

function Button(tagName) {
  this.button = document.createElement(tagName || 'button');
}

Button.prototype.hide = function() {
  this.button.style.display = 'none';
}

Button.prototype.show = function() {
  this.button.style.display = '';
}

window.onload = function() {
  var button = new Button();
  button.button.textContent = 'The button';
  document.body.appendChild(button.button);
  document.getElementById('hideButton').onclick = function(){button.hide()};
  document.getElementById('showButton').onclick = function(){button.show()};
};
<input type="button" id="hideButton" value="Hide the button">
<input type="button" id="showButton" value="Show the button">

Upvotes: 0

Safeer Hussain
Safeer Hussain

Reputation: 1340

Try adding this.button = button; and reference it in applyJsonProperties as this.button.style[cssAttribute] = jsonProperties[cssAttribute]; and remove return button :

function Button(tagName) {
  var button;
  if (tagName) button = document.createElement(tagName);
  else button = document.createElement('div');

  button.innerHTML = 'Track Order';
  this.button = button;
}
Button.prototype.applyJsonProperties = function(jsonProperties){
   if(jsonProperties){
     for(var cssAttribute in jsonProperties){
       this.button.style[cssAttribute] = jsonProperties[cssAttribute];
     }
   }
}

var divButton = new Button('div');
var props = { "color" : "blue" }
divButton.applyJsonProperties(props); 

Upvotes: 1

Rudolf Manusachi
Rudolf Manusachi

Reputation: 2346

Because you return button in Button function.

And your applyjSonProperties returns nothing.

Try something like this:

function Button(tagName) {

  if (tagName) this.button = document.createElement(tagName);
  else this.button = document.createElement(div);

  this.button.innerHTML = 'Track Order';

}
Button.prototype.applyJsonProperties = function(jsonProperties){
  if(jsonProperties){
    for(var cssAttribute in jsonProperties){
      this.button.style[cssAttribute] = jsonProperties[cssAttribute];
    }
  }
  return this; //return modified (or not) instance
}

var divButton = new Button('div');
console.log(divButton.button);

var props = { "color" : "blue" }
divButton.applyJsonProperties(props);
console.log(divButton.button);

Upvotes: 1

Hector Barbossa
Hector Barbossa

Reputation: 5528

Not sure what you are trying to do here. As you are explicitly returning a local variable button from the constructor function, the divButton = new Button('div') will be a div element like <div>Track Order</div>. This element obviously don't have acces to applyJsonProperties function.

Upvotes: 1

Related Questions