Path: csiph.com!usenet.pasdenom.info!dedibox.gegeweb.org!gegeweb.eu!nntpfeed.proxad.net!feeder1-2.proxad.net!proxad.net!feeder2-2.proxad.net!newsfeed.arcor.de!newsspool2.arcor-online.net!news.arcor.de.POSTED!not-for-mail Content-Type: text/plain; charset="UTF-8" Message-ID: <3102322.j8kCu7WbkW@PointedEars.de> From: Thomas 'PointedEars' Lahn Reply-To: Thomas 'PointedEars' Lahn Organization: PointedEars Software (PES) Date: Thu, 25 Oct 2012 00:03:02 +0200 User-Agent: KNode/4.4.11 Content-Transfer-Encoding: 8Bit X-Face: %i>XG-yXR'\"2P/C_aO%~;2o~?g0pPKmbOw^=NT`tprDEf++D.m7"}HW6.#=U:?2GGctkL,f89@H46O$ASoW&?s}.k+&. <67583587.7BbXikoxoM@PointedEars.de> Followup-To: comp.lang.javascript MIME-Version: 1.0 Lines: 191 NNTP-Posting-Date: 25 Oct 2012 00:03:02 CEST NNTP-Posting-Host: 67a2f224.newsspool3.arcor-online.net X-Trace: DXC=]\Be2]9i69UYQ5E:lKPd@Z]ZC][K6Um=jYeIhJRb\ X-Complaints-To: usenet-abuse@arcor.de Xref: csiph.com comp.lang.javascript:16841 Cezary Tomczyk wrote: > W dniu 2012-10-24 03:15, Thomas 'PointedEars' Lahn pisze: >> Cezary Tomczyk wrote: >>> I have read this article: >>> http://perfectionkills.com/extending-built-in-native-objects-evil-or- not/ >>> >>> At the end there is: >>> >>> "[...] It should be now clear that extending native built-ins is >>> definitely not as risky as messing with host objects. Do it carefully, >>> follow spec closely, and use your reasonable judgement.[...]" >>> >>> In my project I use some of the 3-rd party library. I didn't knew that >>> this library overwritten many of built-in native methods. >> Do not use that library then; it is junk. A library should only >> overwrite > > Sometimes it is just impossible. And especially you should know about > that. What are you getting at? I do not use junk libraries, I strongly recommend against them at every opportunity, and I explain why; and I am working on better ones for everybody (including me) to use freely and for free, and to contribute to them. >> Any library that provides an emulation of a built-in method should only >> do that after it has been determined that the built-in method is >> unavailable: > > Yes, but only on one condition: if developer know how to do it in right > way. A developer who does not know how to do it right has failed at their job. >> if (typeof foo.whatever != "function") > > I would use !== here. Its slightly faster than != because there is no > type conversion. Nonsense. `typeof' yields a result of type String. >> { >> foo.whatever = function (…) { >> … >> }; >> } >> >> or even >> >> if (typeof foo.whatever != "undefined") >> { >> foo.whatever = function (…) { >> … >> }; >> } >> >> `foo' should not refer to a host object then. And whenever a built-in >> method is overwritten by a library, it should be done so that the >> specified way of calling that method is still supported. > > But if foo.whatever is defined then I'm not sure if this foo.whatever > working as expected. I mean, as defined in documentation. For example: > https://developer.mozilla.org/en- US/docs/JavaScript/Reference/Global_Objects/String/Trim That is only the documentation of one implementation. Refer to the Specification first. > Maybe its good to write here small unit test and try to check what is > the result from method foo.whatever. Then I can be sure if the method > working well or not. > > Am I correct? Unit tests are always a good idea. >>> And even worst, they work different than they should. I mean, results is >>> not the same as expected. >>> >>> So, when I'm doing: >>> >>> if (String.prototype.trim) >>> >>> and its passed then this means that trim method exists. >> >> No, it means that the String prototype object has a `trim' property whose >> value can be type-converted to `true'. > > As usually, delivering full explanation. :-) String.prototype.trim = 42; if (String.prototype.trim) { /* TypeError */ "foo".trim(); } >>> Is there a way to check if (for example: String.prototype.trim) is a >>> real built-in method? >> >> No (looking for "[native code]" is _not_ reliable; function serialization >> is *implementation-dependent*), and there should not be a need for it. > > I don't know better way to check if method is really built-in. A possibility is to check if the property is enumerable, because user- defined methods tend to be enumerable, while built-in methods tend not to. The built-in trim() method is not enumerable. This is easy and efficient to test in conforming implementations of ECMAScript Edition 5.x (provided that method has not been blindly overwritten too): if (String.prototype.propertyIsEnumerable("trim")) The method can be emulated using a for-in loop, although the emulation will be enumerable by contrast to the built-in: if (typeof Object.prototype.propertyIsEnumerable != "function") { Object.prototype.propertyIsEnumerable = function (name) { for (var propertyName in this) { if (propertyName == name) { return true; } } return false; }; } (But it would probably be better to define it on another object to avoid complications with for-in.) The caveat is that this may be not reliable. It is possible that Object.defineProperty() had been used to define a non-enumerable method. But again, why would you need to check? Either the replacement implementation works *at least* as specified or it does not. In the latter case either it must be considered junk and should not be used in the first place, or you jump through their hoops from then on and rewrite your code to accomodate the overwritten method instead of the behavior defined by the Specification. >> However, you can increase the probabililty that the property (value) is >> callable, and you can handle odd cases (this may be part of a >> user-defined wrapper): >> >> if (typeof bar.trim == "function") >> { >> try >> { >> var foo = bar.trim(); >> } >> catch (e) >> { >> … >> } >> } >> >> try-catch might need to be guarded for a maximum of >> backwards-compatibility: >> >> if (typeof bar.trim == "function") >> { >> eval("try { var foo = bar.trim(); }" >> + "catch (e) { … }"); >> } > > I think its not about if property (value) is callable. Yes, it is. > Even, if property is callable this means only that property (value) is... > callable. There is no guarantee that property (value) will return the > correct result. > Right? Correct. But you cannot test everything. >> See also: http://PointedEars.de/es-matrix> > > I know this table. Good. It will change considerably. -- PointedEars