Thomas 'PointedEars' Lahn wrote:
> Doc O'Leary wrote:
>> Thomas 'PointedEars' Lahn <
Point...@web.de> wrote:
>>> > Andrew Poulos <
ap_...@hotmail.com> wrote:
>>> >> var myObjLayerMoveTo = window.ObjLayerMoveTo;
>>> >>
>>> >> window.ObjLayerMoveTo = function(x, y) {
>>> >> if (
this.id == "foo") return;
>>> >> myObjLayerMoveTo(x, y);
>>> >> };
>>> >>
>>> >> Is this the way to approach this?
>>> > Goodness, no. A major point of OOD is that you can override the
>>> > method in the hierarchy at the appropriate object level.
>>> Pray tell, what would be the object here?
>>
>> Whatever the context “this” is referring to such that the id can be
^^^^^^^^^^^^^^^^^^
>> compared in the first place.
>
> “this” is not necessarily referring to the same object that the function
> is called as a method of.
Also, the statement above speaks of the common misconception that “this” in
ECMAScript implementations referred to a(n execution) context. It does
_not_.
“this” in a function (execution) context refers to the object of which the
function is called as a method, or its value is the “undefined” value.
In normal mode, a *direct* function call is equivalent to calling the
function explicitly as a method of the global object (unless a execution
context before the global context declares a method of the same name).
That is often *misunderstood* as “this” referring to a(n execution) context
(instead of an object), because symbols declared in the global context are
also available as properties of the global object. In strict mode, however,
“this” is undefined in that case.
This – and, literally, “this” – can be implicit, using property accessor
syntax (dot or brackets), for example:
obj.objLayerMoveTo = ObjLayerMoveTo;
obj.objLayerMoveTo(42, 23);
obj["objLayerMoveTo"](42, 23);
This way, “this” inside the called “objLayerMoveTo” *method* would refer to
the same object as “obj”.
But the required first statement is usually unwise with a host object
referred to by “obj” as it would attempt to augment that host object or
override one of its built-in methods.
“this” can also be explicit, using e.g. Function.prototype.call() or
Function.prototype.apply() (there are other possibilities when used as a
callback for e.g. Array prototype methods):
ObjLayerMoveTo.call(obj, 42, 23);
ObjLayerMoveTo.apply(obj, [42, 23]);
That is safe with a host object referred to by “obj” as it does not augment
it, but still unwise here because of the global function (it “pollutes the
global namespace”).
One can surmise from the name of the function and the use of an “id”
property in the one that is to “override” it, that “this” is supposed to
refer to an element object, which is a host object. But while it is
possible to some extent to modify the prototype of host objects – e.g.,
suppose “obj” would refer to a “div” element object,
HTMLDivElement.prototype.objLayerMoveTo = function (x, y) {
/* … */
};
– it is not compatible, and that modification would not have an effect if
the host object had been augmented. Further, modifying the method that the
host object had been augmented with would compound this former mistake with
the same one.
However, it should be noted that if something like
obj.objLayerMoveTo = ObjLayerMoveTo;
or
obj.onmouseover = ObjLayerMoveTo;
had been executed *before*, then, *without* changing more code, it would be
necessary to do that anyway. [The latter assignment would also be _safe_
and _not_ a mistake by contrast because the values of those (event-handler)
properties of element objects are *designed* to be modified that way.]
Because the suggested redefinition of the function would not change the
reference value that had been assigned to the property of the object
referred to by “obj”:
obj
:
v
,-----------------------.
| : object[Element] |
|-----------------------|
| … |
| +… ----------------------.
| … | :
`-----------------------' : (refers to)
:
,------------------------'
:
: ,-----------------------------------.
`-->| : function[Function] |
|-----------------------------------|
| … |
| +name : string = "ObjLayerMoveTo" |
| … |
`-----------------------------------'
^
. calls
.
,-----------------------------------.
,-->| : function[Function] |
: |-----------------------------------|
: | … |
: | +name : string = "ObjLayerMoveTo" |
: | … |
: `-----------------------------------'
:
`--------------------------.
:
,-------------------------. :
| global : object[Object] | :
|-------------------------| :
| … | :
| +ObjLayerMoveTo -----------'
| … |
`-------------------------'
This is the only way where I think that the *generally* sound idea to
“override the method in the hierarchy at the appropriate object level”
would hold *some* water in *this* case.
Not so if something like
ObjLayerMoveTo.call(obj, 42, 23);
or
ObjLayerMoveTo.apply(obj, [42, 23]);
had been used instead, as “ObjLayerMoveTo” would only be resolved when
execution reached those lines (closure).