My JavaScript code:
console.clear();
function BaseClass(nname) {
var name = nname;
this.bc_PublicProperty = "DefaultValue_BaseClass";
this.bc_getName = function GetName() {
return name;
};
this.bc_setName = function SetName(nname) {
name = nname;
};
}
function SubClass(nname) {
BaseClass.call(this, nname);
this.sc_PublicProperty = "DefaultValue_SubClass";
this.sc_getName = function GetName() {
return name;
};
this.sc_setName = function SetName(nname) {
name = nname;
};
}
SubClass.prototype = Object.create(BaseClass.prototype);
SubClass.prototype.constructor = SubClass;
var bc = new BaseClass("Anton");
var sc = new SubClass("Bernd");
console.log("hasOwnProperty check on subclass object 'sc' returns true for Method 'bc_getName'");
for (var pro in sc) {
console.log("Is " + pro + " own property of subclass: --> " + Object.hasOwnProperty.call(sc, pro));
}
I have two objects (BaseClass and SubClass). One inherits from the other using the constructor pattern, as explained on MDN.
Now, when I iterate over all properties of the subclass object, they all return true for hasOwnProperty, even for the parent methods/properties, except constructor.
Does it mean, that it breaks when using the constructor pattern?
When I put public properties and methods in the constructor function, whether in BaseClass or SubClass, they will always be "marked" as own properties/methods. When I instead attach them to the respective prototype, the hasOwnProperty will output "false" for them.
Whether you put the public methods/properties to the prototype or to the constructor function itself, they will all be available for use in the subClass (--> SubClass2, --> SubClass3).
The only thing, that I can think of right now, why you should attach them to the prototype object, is because of efficiency reasons, as explained here, "Defining class methods"-section. In order not to add closures for every constructed instance.
Value Types should be declared on the prototype, but not for instance variables whose initial values are dependent on arguments to the constructor, or some other state at time of construction. You can override both properties/functions irrespective of their place of declaration.
Also setting up getters and setters on the prototype, for instance to set or get a private variable, makes no sense, as the private variable has to be public, in order to be accessible by the getters and setters attached to the prototype.
Therefore it makes no sense to use getters and setters. You can access the public variable directly.
I have to adjust my question a bit now:
When do I need hasOwnProperty, if actually public props/functions should be declared on the prototype, which in turn will all output Object.hasOwnProperty(obj,"prop/func") --> false. Give me a use case, when it makes sense, to use hasOwnProperty.
console.clear();
var l = function(v) {
console.log(v);
};
function BaseClass(nname) {
this.bc_nameProp = nname;
this.bc_ownFunc = function() {
l("bc_ownFunc of BaseClass called");
};
this.bc_getName = function GetName() {
return this.bc_nameProp;
};
}
BaseClass.prototype.bc_getName = function GetName() {
return this.bc_nameProp;
};
BaseClass.prototype.bc_PublicProperty = "DefaultValue_BaseClass";
BaseClass.prototype.bc_setName = function SetName(nname) {
bc_nameProp = nname;
};
function SubClass(nname) {
BaseClass.call(this, nname);
this.sc_setName = function SetName(nname) {
bc_nameProp = nname;
};
this.bc_getName = function GetName() {
return "xyz";
};
}
SubClass.prototype = Object.create(BaseClass.prototype);
SubClass.prototype.constructor = SubClass;
SubClass.prototype.sc_getName = function GetName() {
return this.bc_nameProp;
};
SubClass.prototype.sc_PublicProperty = "DefaultValue_SubClass";
var bc = new BaseClass("Anton");
var sc = new SubClass("Bernd");
l("----- iterating over BaseClass properties ------");
l("");
for (var pro in bc) {
l("Is " + pro + " own property of BaseClass: --> " + Object.hasOwnProperty.call(bc, pro));
}
l("");
l("----- iterating over SubClass properties ------");
l("");
for (var p in sc) {
l("Is " + p + " own property of subclass: --> " + Object.hasOwnProperty.call(sc, p));
}
l(bc.bc_getName());
l(sc.bc_getName());
l(sc.sc_getName());
Solution
When I asked this question, I was of the opinion, that when using classical inheritance in JavaScript, I can differentiate which properties/functions of my subclass directly belong to it, using hasOwnProperty. Which is not possible, as all the properties/functions of the parent prototype are copied to the prototype of the SubClass:
SubClass.prototype = Object.create(BaseClass.prototype);
All properties/functions attached to prototypes return "false", when using hasOwnProperty.
And if you have public properties/functions declared in the constructor functions of BaseClass and SubClass, all these properties return "true", when calling hasOwnProperty for these properties on the subclass.
These are copied to the SubClass using this statement:
BaseClass.call(this, nname);
So using hasOwnProperty while iterating over all properties of an obj of type SubClass, will output false for all properties/functions declared on prototype level and true for all properties/functions declared on constructor function level.
Now, I understand why using hasOwnProperty in this use case makes no sense.