Path: csiph.com!weretis.net!feeder4.news.weretis.net!feeder5.news.weretis.net!news.solani.org!.POSTED!not-for-mail From: Thomas 'PointedEars' Lahn Newsgroups: comp.lang.javascript Subject: Re: Empty function Date: Sun, 08 Jan 2017 23:21:39 +0100 Organization: PointedEars Software (PES) Lines: 119 Message-ID: <8026292.CDJkKcVGEf@PointedEars.de> References: Reply-To: Thomas 'PointedEars' Lahn Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Trace: solani.org 1483914101 17994 eJwNycEBwCAIA8CVioEg4yDI/iPY+56BwnKlUW1s7ortffAJWXVE515dUQmBoTv7bw9kCnIPHyEYEWE= (8 Jan 2017 22:21:41 GMT) X-Complaints-To: abuse@news.solani.org NNTP-Posting-Date: Sun, 8 Jan 2017 22:21:41 +0000 (UTC) User-Agent: KNode/4.14.2 X-User-ID: eJwFwYEBwCAIA7CXqEDRczqU/09Ykk6wK5iMnJx3hK8x4na+FqJVWpBtDuw+AVcPpZijU3BrKGNf2kL7D3I3FcY= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAGFBMVEXTxa4RFk5dUWANED8PFEfy7+MGBiW+n3ZNF/QuAAACaElEQVQ4jVXUwVOcMBQG8Dc7Rc4PUntdWV2uxjDpGaGeozOp1woar4jd5t/v9wLstMwsA/ntlxdCAgUc1hjTc9/JCZfGoo3wG3HdmdAWrIJRHe7GM/TmpY5VFefuVcAkkPbLIaN8rmPmjloyZxgyR3GuJ4K0AGtJ2htz8o7yqikm759fldQXaMpbDzjKAG+8v+AugVTOPO5DOjLvGtUYQwh0CPjnVMyGd+8/GfUB5nLKJDD2aLDh5HYyMDJGDwQIo2ZmZcKbowNmAdB/AzyFhrmF2MHRb0QJJfaAnwGB6orZhoykLzJtGwF/xpYxI1dswomiUj3gTuAIqCn/4C7cULwGNBtwMTk3Y4LfKB5YUaOKBKYtpplm7u0vip8tU1NWWyI/7XdcSuIDoMt6rVHMWT0DbjHPGqDqZVSa6zleLcUTcIKLoMv3ueJluALtAo9B302zPPlrtiVScRdCjXvVh3e3JpYa/jjkuC9N+LrBMlz/eAN4eQijX2EdLo6c5tGGHwLyHFtXk89dDGHwCVhG9T0S/j55AhRZgkMCmUQXJ49TnS1wnQDvw0eAh9ICeMmEFbCnPMFzjAvsWoEWEFdYEx+S0MoUZ1gT1wId8+AF3Bl2OoEu906AUHx5VLw/gXYg/x84loOah/2UYNrgiwSwGO7RfUzVBbx/kgpckumGOi6QirtD6gkLTitbnxNol47S2jVc2vsN5kPqaAHT8uUdAJM4v/DanjYOwmUjWznGfwB7sGtAtor5BgofDuzaRj4kSQAqDakTsKORa3Q3xKi3gE1fhl71KRMqrdZ2AWNNg/YOhQyrVBnb+i+nEg4bsDA+egAAAABJRU5ErkJggg== X-Face: %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&. I'm needing to edit some code that's been given to me. Apparently its > been written a decade or so ago. Paraphrased, the code follows: > > var Drag = { > obj : null, > init: function(o) { > o.onmousedown = Drag.start; > o.root.onDrag = function() {}; //--> what does this line do? > }, > start: function(e) { > document.onmousemove = Drag.drag; > document.onmouseup = Drag.end; > return false; > }, > drag: function(e) { > Drag.obj.root.onDrag(nx, ny); > return false; > }, > end: function() { > document.onmousemove = null; > document.onmouseup = null; > } > }; > > What I don't follow is what the line > o.root.onDrag = function() {}; > is doing. If I comment the line out the code "doesn't work". What's the > purpose of setting an event to an empty function? That “onDrag” is an "event" is your jump to conclusions, and a wrong one at that (read up on events). It could merely be an event-_handler property_, and then it would be a user-defined or proprietary one (AFAIK, all standard event-handler properties have all-lowercase names). For now, however, it is just the name of an ordinary property. In the drag() method of the object referred to by “Drag”, that property needs to be callable. That is why the code “doesn’t work” if you comment out the initialization (as you could have seen in the error console; see the FAQ). This appears to be a lazy person’s approach to avoid feature tests in the drag() method. It is error-prone as long as the property that is supposed to be callable there is (publicly) writable (and it appears to be so here), because then when the “drag” method is called, the “onDrag” property value can be any (even a non-callable) value even if the init() method had been called before. It is also memory-inefficient because even if an onDrag() method is never required to be called, heap memory is being reserved for storing the Function instance referred to by onDrag(). The code also appears to violate the Law of Demeter because it performs a write access to a property of an object referred to by one of the properties of an object whose reference was passed to the init() method. The init() method should delegate that action by calling a method of the referred object instead. Contrary to common misconception, it is also insufficient and potentially error-prone (not all host object’s methods take kindly to that test) to test a property for being a true-value in order to ascertain that it is callable: foo.bar = 42; /* Do not do this */ if (foo.bar) { foo.bar(); } The safest way is to subject it(s value) to a “typeof” test; should that operation yield "function", then it is very likely that the property value is callable (since ECMAScript Ed. 5 it is a requirement even for host object’s methods to behave this way): /* * You can also use “===”, but it is not strictly necessary * (no pun intended) due to the result of the “typeof” operation */ if (typeof foo.bar == "function") { foo.bar(); } [Although it is tempting to wrap that test in a method because it can become tedious to write and it takes more space, it turned out that doing so actually reduces the runtime efficiency of the code because of the overhead of the method’s identifier resolution, property lookup, and method call when compared to the simple operation. Therefore, a wrapping method should only be used if it accomplishes more than this simple test. For example, jsx.object.isNativeMethod()/.areNativeMethods() prevails in JSX:object.js because it can test along a “property path” and multiple “leaf” properties in one call. Work is in progress to remove all unnecessary calls to this method from JSX.] The only completely safe solution regarding a call, however less backwards- compatible and error-prone because it can result in false negatives, is to use a try…catch statement in which to attempt the call: try { foo.bar(); } catch (e) { if (e instanceof TypeError) { /* handle problem */ } } It is error-prone because, in theory, the called method and any method that is called by it could throw a TypeError exception. Also, one must be careful not to catch too many exceptions with one try…catch statement, making the source code harder to debug. -- PointedEars FAQ: | | Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.