You might also question the need to have a - getId - method at all, when
the - id - property it returns (unaltered) is already public and can be
read (and set) directly from the object.
You are right. I was just trying to see how this kind of
code can be optimized a bit;
function Customer(...) {
function getId() {...}
if(typeof this.constructor.prototype.done == 'undefined') {
this.constructor.prototype.getId=getID;
this.constructor.prototype.done=1;
}
}
}
There is plenty of potential for optimising the test in addition to the
actions following from the passing of the test. The evaluation of the -
if - expression currently involves; resolving a property accessor,
applying the unary - typeof - operator to the result, comparing the
result of that with a string literal and finally type-converting that
result to boolean to make the - if - decision (the last being a trivial
operation as the result of the comparison is already boolean). Given
that the property accessor resolves to a value that is either undefined
or (in this example) numeric one, applying the NOT operator to the
property accessor as the - if - expression:-
if(!this.constructor.prototype.done){
...
}
- produce identical results, as the unary NOT operator will type-convert
the value to boolean and invert it, resulting in false for numeric 1 and
true for undefined, without the need for any other operations. The
overall result will be considerably faster (string comparison being
quite an involved operation when the strings being tested actually do
match, and the typeof algorithm specifying an additional safety check
that NOT does not use (and is irrelevant in this context).
Additionally, the property accessor - this.constructor.prototype.done -
will take longer to resolve than - this.done -, and in the context of
its use in the opening lines of a constructor the two will be reporting
the same value (- this - having inherited its - done - value (if any)
from the constructor's prototype).
But it is questionable whether the - done - flag is required at all as
applying a type-converting test (or even the less efficient - typeof -
test) to any of the methods assigned will produce equivalent result, and
avoid the need to assign a - done - value:
if(!this.getId){
this.constructor.prototype.getId = getId;
}
Repeatedly resolving - this.constructor.prototype - during the
assignments will also become burdensome if it needs to be done more than
a couple of times. The prototype object reference could be cached to a
local variable to reduce that overhead.
However, overall it has got to be fastest and simplest to configure the
constructor's prototype unconditionally outside of the constructor.
Other object designs, those implementing Douglas Crockford's private
instance members technique, attempting multiple inheritance or
implementing common interfaces shared by many classes/subclasses, might
necessitate alternative inheritance patterns (mostly forms of object
augmentation) but the simple javascript objects benefit most from
following the standard javascript prototype inheritance pattern.
as Richard pointed out, upon each Customer object creation,
a function object will be created for getId function
declaration;
Didn't I also mention the overhead in repeating the tests on each object
instantiation?
I guess realistically it may not a problem when only
one or just a few are created; so I tried to see if it
can be created dynamically (I mean using function declarations,
not function expressions) and if there will be any advantages.
It appears though that the 'fastest' approach is this -|
function Customer(...) {
this.constructor.prototype.getId=function () {};
}
}
'fastest'?
Richard.