Reputation: 2224
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
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
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
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
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