Path: csiph.com!aioe.org!news.mb-net.net!open-news-network.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Overriding function and adding a bit Date: Thu, 11 May 2017 17:03:08 +0200 Organization: PointedEars Software (PES) Lines: 160 Message-ID: <3160292.R56niFO833@PointedEars.de> References: <5178377.MhkbZ0Pkbq@PointedEars.de> <20479369.6Emhk5qWAg@PointedEars.de> Reply-To: Thomas 'PointedEars' Lahn NNTP-Posting-Host: 170.224.197.178.dynamic.wless.zhbmb00p-cgnat.res.cust.swisscom.ch Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: gwaiyur.mb-net.net 1494514990 21996 178.197.224.170 (11 May 2017 15:03:10 GMT) X-Complaints-To: abuse@open-news-network.org NNTP-Posting-Date: Thu, 11 May 2017 15:03:10 +0000 (UTC) User-Agent: KNode/4.14.2 X-Face: %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&. Doc O'Leary wrote: >> Thomas 'PointedEars' Lahn wrote: >>> > Andrew Poulos 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). -- PointedEars Twitter: @PointedEars2 Please do not cc me. / Bitte keine Kopien per E-Mail.