Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #16921

Re: Built-in native method

From Cezary Tomczyk <cezary.tomczyk@gmail.com>
Newsgroups comp.lang.javascript
Subject Re: Built-in native method
Date 2012-10-28 15:32 +0100
Organization Aioe.org NNTP Server
Message-ID <k6jfld$q6l$1@speranza.aioe.org> (permalink)
References <k5sbuj$bt8$1@speranza.aioe.org> <67583587.7BbXikoxoM@PointedEars.de> <k69jek$r9i$1@speranza.aioe.org> <3102322.j8kCu7WbkW@PointedEars.de>

Show all headers | View raw


W dniu 2012-10-25 00:03, Thomas 'PointedEars' Lahn pisze:
> 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.

It's not about me. I just can't change it.

>>> 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.

You never make mistakes? I don't believe in it.

>>>     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.

That's weird for me. I thought that === will be much faster than == 
because there is no internal type conversion. I created the test:

http://jsperf.com/typeof-equals-triple-double

and its seems that == is even sometimes faster. But it depends on browser.

However, JSHint report me that I need replace every == by === because 
settings in JSHint require always ===. I wonder why this is required in 
our project by other developers? Correct me if I'm wrong, but if we know 
what type of object will be then there is no need to use ===, right?

>>>     {
>>>       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.

You mean this one: 
http://ecma-international.org/ecma-262/5.1/#sec-15.5.4.20 ?

>> 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.

Of course.

>>>> 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();
>    }

That's possible. Then we should here check if String.prototype.trim is a 
function, right?

>>>> 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.

Thanks for explanation.

However, as for question "why I need to check it?". Reason is simple: 
library, which is included in project, have a few methods (not only 
"trim") that are very badly implemented. Trim is just one of them.

What I want to get? I want to use built-in trim method only if it is 
really built-in or use my custom trim method. Because trim that coming 
from external library (by extending native built-in object String) is 
badly implemented.

>>> 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.

After study your example more closely then I must say: you were right.

>> 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.

That's true.

-- 
Cezary Tomczyk
http://www.ctomczyk.pl/

Back to comp.lang.javascript | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-19 22:07 +0200
  Re: Built-in native method JJ <jaejunks_at@_googlemail_dot._com> - 2012-10-21 06:44 +0000
    Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-21 18:46 +0200
    Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-21 19:37 +0200
      Re: Built-in native method Andreas Bergmaier <andber93@web.de> - 2012-10-22 15:47 +0200
        Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-22 18:00 +0200
          Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-24 02:17 +0100
            Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-24 22:17 +0200
              Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-25 00:32 +0200
  Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-24 02:15 +0100
    Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-24 22:35 +0200
      Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-25 00:03 +0200
        Re: Built-in native method Asen Bozhilov <asen.bozhilov@gmail.com> - 2012-10-26 03:58 -0700
          Re: Built-in native method RobG <rgqld@iinet.net.au> - 2012-10-29 16:39 -0700
        Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-28 15:32 +0100
          Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-28 17:05 +0100
            Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-28 18:39 +0100
              Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-28 20:10 +0100
                Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-28 20:23 +0100
                Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-28 21:23 +0100
                Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-28 22:03 +0100
        Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-28 15:49 +0100
          Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-28 17:12 +0100
            Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-28 17:49 +0100
              Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-28 18:07 +0100
                Re: Built-in native method Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2012-10-28 19:22 +0100
                Re: Built-in native method Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2012-10-28 19:53 +0100

csiph-web