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


Groups > comp.lang.javascript > #16841

Re: Built-in native method

Message-ID <3102322.j8kCu7WbkW@PointedEars.de> (permalink)
From Thomas 'PointedEars' Lahn <PointedEars@web.de>
Organization PointedEars Software (PES)
Date 2012-10-25 00:03 +0200
Subject Re: Built-in native method
Newsgroups comp.lang.javascript
References <k5sbuj$bt8$1@speranza.aioe.org> <67583587.7BbXikoxoM@PointedEars.de> <k69jek$r9i$1@speranza.aioe.org>
Followup-To comp.lang.javascript

Followups directed to: comp.lang.javascript

Show all headers | View raw


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

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