Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #16740 > unrolled thread
| Started by | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| First post | 2012-10-19 22:07 +0200 |
| Last post | 2012-10-28 19:53 +0100 |
| Articles | 20 on this page of 27 — 6 participants |
Back to article view | Back to comp.lang.javascript
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
Page 1 of 2 [1] 2 Next page →
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-19 22:07 +0200 |
| Subject | Built-in native method |
| Message-ID | <k5sbuj$bt8$1@speranza.aioe.org> |
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. 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. The only problem is that I cannot be sure if this works correctly or if the native built-in method is not overwritten by someone else. Is there a way to check if (for example: String.prototype.trim) is a real built-in method? -- Cezary Tomczyk http://www.ctomczyk.pl/
[toc] | [next] | [standalone]
| From | JJ <jaejunks_at@_googlemail_dot._com> |
|---|---|
| Date | 2012-10-21 06:44 +0000 |
| Message-ID | <XnsA0F38C4E46019jaejunksgooglemailco@0.0.0.44> |
| In reply to | #16740 |
Cezary Tomczyk <cezary.tomczyk@gmail.com> wrote:
> So, when I'm doing:
>
> if (String.prototype.trim)
>
> and its passed then this means that trim method exists. The only problem
> is that I cannot be sure if this works correctly or if the native
> built-in method is not overwritten by someone else.
>
> Is there a way to check if (for example: String.prototype.trim) is a
> real built-in method?
The code inside native functions are syntatically incorrect. You can use
this to check them. For example, the "escape" function (any function will
do):
var a=escape.toString();
console.log(a);
//Firefox/Safari: "function escape() {\n [native code]\n}"
//Chrome/MSIE/Opera: "function escape() { [native code] }"
You see that the code contains only an expression, which is an array. The
array contains only one expression, which is "native code". i.e.: two
references to identifiers which are neither reserved word, variable,
function nor object. This expression is not correct and will cause a syntax
error exception.
The easiest way to check it is to use the "eval" function to check whether
an existing function is syntatically correct or not.
function isNativeFunc(f) {
var a, z;
if (typeof f == 'function') {
//is a function
try {
a = f.toString();
eval('(function(){'+a+'})()');
return false;
} catch(z) {
//syntax error
return true;
}
} else {
//not a function. assume false
return false;
}
}
console.log(isNativeFunc(escape));
//shows: true
console.log(isNativeFunc(isNativeFunc));
//shows: false
Note that the usage of "eval" is considered as unsafe. So, since there's no
direct alternative for that method, parsing is neccessary. A regular
expression is used for this method.
function isNativeFunc(f) {
if (typeof f == 'function') {
//is a function
var a = f.toString();
//reg-exp for native function code block format
var r = /[^{]+\{[\n ]+\[[a-z]+ [a-z]+\][\n ]+\}$/im;
return a.match(r) != null;
} else {
//not a function. assume false
return false;
}
}
console.log(isNativeFunc(escape));
//shows: true
console.log(isNativeFunc(isNativeFunc));
//shows: false
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-21 18:46 +0200 |
| Message-ID | <k618t0$2d5$1@speranza.aioe.org> |
| In reply to | #16762 |
W dniu 2012-10-21 08:44, JJ pisze:
> Cezary Tomczyk <cezary.tomczyk@gmail.com> wrote:
>> So, when I'm doing:
>>
>> if (String.prototype.trim)
>>
>> and its passed then this means that trim method exists. The only problem
>> is that I cannot be sure if this works correctly or if the native
>> built-in method is not overwritten by someone else.
>>
>> Is there a way to check if (for example: String.prototype.trim) is a
>> real built-in method?
>
> The code inside native functions are syntatically incorrect. You can use
> this to check them. For example, the "escape" function (any function will
> do):
>
> var a=escape.toString();
> console.log(a);
> //Firefox/Safari: "function escape() {\n [native code]\n}"
> //Chrome/MSIE/Opera: "function escape() { [native code] }"
>
> You see that the code contains only an expression, which is an array. The
> array contains only one expression, which is "native code". i.e.: two
> references to identifiers which are neither reserved word, variable,
> function nor object. This expression is not correct and will cause a syntax
> error exception.
I completely forgot about "[native code]".
> The easiest way to check it is to use the "eval" function to check whether
> an existing function is syntatically correct or not.
>
> function isNativeFunc(f) {
> var a, z;
> if (typeof f == 'function') {
> //is a function
> try {
> a = f.toString();
> eval('(function(){'+a+'})()');
> return false;
> } catch(z) {
> //syntax error
> return true;
> }
> } else {
> //not a function. assume false
> return false;
> }
> }
>
> console.log(isNativeFunc(escape));
> //shows: true
> console.log(isNativeFunc(isNativeFunc));
> //shows: false
>
> Note that the usage of "eval" is considered as unsafe. So, since there's no
> direct alternative for that method, parsing is neccessary. A regular
> expression is used for this method.
>
> function isNativeFunc(f) {
> if (typeof f == 'function') {
> //is a function
> var a = f.toString();
> //reg-exp for native function code block format
> var r = /[^{]+\{[\n ]+\[[a-z]+ [a-z]+\][\n ]+\}$/im;
> return a.match(r) != null;
> } else {
> //not a function. assume false
> return false;
> }
> }
>
> console.log(isNativeFunc(escape));
> //shows: true
> console.log(isNativeFunc(isNativeFunc));
> //shows: false
Thank you for explanation. Make sense. I have no more questions in this
topic.
--
Cezary Tomczyk
http://www.ctomczyk.pl/
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-21 19:37 +0200 |
| Message-ID | <k61bt0$b4a$1@speranza.aioe.org> |
| In reply to | #16762 |
W dniu 2012-10-21 08:44, JJ pisze:
> Cezary Tomczyk <cezary.tomczyk@gmail.com> wrote:
[...]
> function isNativeFunc(f) {
> if (typeof f == 'function') {
> //is a function
> var a = f.toString();
> //reg-exp for native function code block format
> var r = /[^{]+\{[\n ]+\[[a-z]+ [a-z]+\][\n ]+\}$/im;
> return a.match(r) != null;
> } else {
> //not a function. assume false
> return false;
> }
> }
I've just little bit improved the code:
http://jsfiddle.net/DbGVS/
Any advice or comments are appreciated.
--
Cezary Tomczyk
http://www.ctomczyk.pl/
[toc] | [prev] | [next] | [standalone]
| From | Andreas Bergmaier <andber93@web.de> |
|---|---|
| Date | 2012-10-22 15:47 +0200 |
| Message-ID | <k63ip3$lj4$1@news.albasani.net> |
| In reply to | #16766 |
Cezary Tomczyk schrieb: > I've just little bit improved the code: > http://jsfiddle.net/DbGVS/ > > Any advice or comments are appreciated. It must be a bit more complicated. Also non-native functions can contain the string '[native code]' - most prominently your isNativeMethod function: http://jsfiddle.net/DbGVS/3/ regards, Bergi
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-22 18:00 +0200 |
| Message-ID | <k63qjg$2b4$1@speranza.aioe.org> |
| In reply to | #16792 |
W dniu 2012-10-22 15:47, Andreas Bergmaier pisze: > Cezary Tomczyk schrieb: >> I've just little bit improved the code: >> http://jsfiddle.net/DbGVS/ >> >> Any advice or comments are appreciated. > > It must be a bit more complicated. Also non-native functions can contain > the string '[native code]' - most prominently your isNativeMethod > function: http://jsfiddle.net/DbGVS/3/ Yes, it's is possible. There is a risk. At this moment I don't know better method. -- Cezary Tomczyk http://www.ctomczyk.pl/
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-10-24 02:17 +0100 |
| Message-ID | <2863979.M2cLrOPMcC@PointedEars.de> |
| In reply to | #16799 |
Cezary Tomczyk wrote:
> W dniu 2012-10-22 15:47, Andreas Bergmaier pisze:
>> Cezary Tomczyk schrieb:
>>> I've just little bit improved the code:
>>> http://jsfiddle.net/DbGVS/
>>>
>>> Any advice or comments are appreciated.
>>
>> It must be a bit more complicated. Also non-native functions can contain
>> the string '[native code]' - most prominently your isNativeMethod
>> function: http://jsfiddle.net/DbGVS/3/
>
> Yes, it's is possible. There is a risk. At this moment I don't know
> better method.
The better way is to cure the disease and not the symptoms: Use a better
library in the first place, and tell the author(s) of the first library
that and how they screwed up so that they can learn from that mistake and
make it better.
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-24 22:17 +0200 |
| Message-ID | <k69ic1$o34$1@speranza.aioe.org> |
| In reply to | #16828 |
W dniu 2012-10-24 03:17, Thomas 'PointedEars' Lahn pisze: > Cezary Tomczyk wrote: > >> W dniu 2012-10-22 15:47, Andreas Bergmaier pisze: >>> Cezary Tomczyk schrieb: >>>> I've just little bit improved the code: >>>> http://jsfiddle.net/DbGVS/ >>>> >>>> Any advice or comments are appreciated. >>> >>> It must be a bit more complicated. Also non-native functions can contain >>> the string '[native code]' - most prominently your isNativeMethod >>> function: http://jsfiddle.net/DbGVS/3/ >> >> Yes, it's is possible. There is a risk. At this moment I don't know >> better method. > > The better way is to cure the disease and not the symptoms: Use a better > library in the first place, and tell the author(s) of the first library > that and how they screwed up so that they can learn from that mistake and > make it better. Oh well. I would like to tell them, but they probably will not be listen. -- Cezary Tomczyk http://www.ctomczyk.pl/
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-10-25 00:32 +0200 |
| Message-ID | <3522868.MSM1jvRdVV@PointedEars.de> |
| In reply to | #16839 |
Cezary Tomczyk wrote: > W dniu 2012-10-24 03:17, Thomas 'PointedEars' Lahn pisze: >> Cezary Tomczyk wrote: >>> W dniu 2012-10-22 15:47, Andreas Bergmaier pisze: >>>> Cezary Tomczyk schrieb: >>>>> I've just little bit improved the code: >>>>> http://jsfiddle.net/DbGVS/ >>>>> >>>>> Any advice or comments are appreciated. >>>> It must be a bit more complicated. Also non-native functions can >>>> contain the string '[native code]' - most prominently your >>>> isNativeMethod function: http://jsfiddle.net/DbGVS/3/ >>> Yes, it's is possible. There is a risk. At this moment I don't know >>> better method. >> The better way is to cure the disease and not the symptoms: Use a better >> library in the first place, and tell the author(s) of the first library >> that and how they screwed up so that they can learn from that mistake and >> make it better. > > Oh well. I would like to tell them, but they probably will not be listen. The logical course of action should be clear by now. PointedEars -- Anyone who slaps a 'this page is best viewed with Browser X' label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network. -- Tim Berners-Lee
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-10-24 02:15 +0100 |
| Message-ID | <67583587.7BbXikoxoM@PointedEars.de> |
| In reply to | #16740 |
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
built-in methods (that is, the properties that refer to the respective
Function objects) when they do _not_ exist, or are not as capable as
required (if it is reasonable to use this and no other method). Built-in
methods are inevitably faster than user-defined ones because in most of the
cases the former are already compiled.
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:
if (typeof foo.whatever != "function")
{
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.
For example, it has been reasonable (but may be considered obsolete now) to
overwrite a not-as-capable Math.max() method:
/**
* Returns the numeric maximum of all arguments.
*
* @params : Number
* @return {Number}
* <code>-Infinity</code> if no arguments have been passed.
*/
function Math_max ()
{
var result = Number.NEGATIVE_INFINITY;
/* NOTE: Array.prototype.slice() was not specified before ES 3 */
for (var i = arguments.length; i--;)
{
var arg = parseFloat(arguments[i]);
if (arg > result)
{
result = arg;
}
}
return result;
}
var x;
if (typeof Math.max == "function")
{
x = Math.max(1, 2, 3);
}
if (typeof x == "undefined" || x != 3)
{
Math.max = Math_max;
}
> 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'.
> 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.
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) { … }");
}
See also: http://PointedEars.de/es-matrix>
PointedEars
--
> If you get a bunch of authors […] that state the same "best practices"
> in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
-- Richard Cornford, comp.lang.javascript, 2011-11-14
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-24 22:35 +0200 |
| Message-ID | <k69jek$r9i$1@speranza.aioe.org> |
| In reply to | #16829 |
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.
> built-in methods (that is, the properties that refer to the respective
> Function objects) when they do _not_ exist, or are not as capable as
> required (if it is reasonable to use this and no other method). Built-in
> methods are inevitably faster than user-defined ones because in most of the
> cases the former are already compiled.
Generally speaking I agree. However, I don't why they wrote many methods
in a wrong way. I can't relay on their methods and that's why I just
wanted to check if method is really native method. There is no perfect
solution.
> 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.
> if (typeof foo.whatever != "function")
I would use !== here. Its slightly faster than != because there is no
type conversion.
> {
> 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
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?
> For example, it has been reasonable (but may be considered obsolete now) to
> overwrite a not-as-capable Math.max() method:
>
> /**
> * Returns the numeric maximum of all arguments.
> *
> * @params : Number
> * @return {Number}
> * <code>-Infinity</code> if no arguments have been passed.
> */
> function Math_max ()
> {
> var result = Number.NEGATIVE_INFINITY;
>
> /* NOTE: Array.prototype.slice() was not specified before ES 3 */
> for (var i = arguments.length; i--;)
> {
> var arg = parseFloat(arguments[i]);
> if (arg > result)
> {
> result = arg;
> }
> }
>
> return result;
> }
>
> var x;
>
> if (typeof Math.max == "function")
> {
> x = Math.max(1, 2, 3);
> }
>
> if (typeof x == "undefined" || x != 3)
> {
> Math.max = Math_max;
> }
>
>> 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. :-)
>> 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.
> 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. 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?
> See also: http://PointedEars.de/es-matrix>
I know this table.
> PointedEars
--
Cezary Tomczyk
http://www.ctomczyk.pl/
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-10-25 00:03 +0200 |
| Message-ID | <3102322.j8kCu7WbkW@PointedEars.de> |
| In reply to | #16840 |
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
[toc] | [prev] | [next] | [standalone]
| From | Asen Bozhilov <asen.bozhilov@gmail.com> |
|---|---|
| Date | 2012-10-26 03:58 -0700 |
| Message-ID | <b02b42e6-1fa8-407e-b348-52627eda24ee@q4g2000vbg.googlegroups.com> |
| In reply to | #16841 |
Thomas 'PointedEars' Lahn wrote:
> 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;
> };
> }
Unfortunately there is not a way to implement shim for
`propertyIsEnumerable'. While I think you solution is right, ECMA-262
has a "bug" in `propertyIsEnumerable'. It does not consider the
prototype chain of the object. So if looking property is not an own
property, the built-in function returns false, while your version is
looking for the property in the prototype chain.
There is also a bug filled by David Flanagan:
<URL: https://bugzilla.mozilla.org/show_bug.cgi?id=57048>
Even Brandon thinks that is a bug in the specification, but someone
has "fixed" the early SpiderMonkey and leaved the specification with
that error.
[toc] | [prev] | [next] | [standalone]
| From | RobG <rgqld@iinet.net.au> |
|---|---|
| Date | 2012-10-29 16:39 -0700 |
| Message-ID | <56c5a798-6ba5-4ff0-bcfa-dd49135d5b88@googlegroups.com> |
| In reply to | #16891 |
On Friday, 26 October 2012 20:58:39 UTC+10, Asen Bozhilov wrote:
> Thomas 'PointedEars' Lahn wrote:
>
> > 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)
Since propertyIsEnumerable only considers own properties, that should probably be:
if (this.hasOwnProperty(propertyName) && propertyName == name)
Of course if hasOwnProperty isn't implemented, life is a bit tougher.
>
> > {
> > return true;
> > }
> > }
> >
> > return false;
> > };
> > }
>
> Unfortunately there is not a way to implement shim for
> `propertyIsEnumerable'. While I think you solution is right, ECMA-262
> has a "bug" in `propertyIsEnumerable'. It does not consider the
> prototype chain of the object. So if looking property is not an own
> property, the built-in function returns false, while your version is
> looking for the property in the prototype chain.
Doesn't the inclusion of a hasOwnProperty test overcome that? There are versions of Safari (< 2?) that don't have hasOwnProperty, propertyIsEnumerable can be used as an alternative.
And yes, it does seem illogical that the [[Prototype]] chain is ignored.
Also, it seems that __proto__ is making a comeback[1], so it might be possible to iterate over enumerable properties of an object and ignore those on the [[Prototype]] chain by comparing to the object's __proto__.
There is also the ES5 Object.getPrototypeOf[2], however it's difficult to see any implementation having getPrototypeOf or __proto__ and not having both propertyIsEnumerable and hasOwnProperty.
1. https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/proto
2. http://ecma-international.org/ecma-262/5.1/#sec-15.2.3.2
--
Rob
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-28 15:32 +0100 |
| Message-ID | <k6jfld$q6l$1@speranza.aioe.org> |
| In reply to | #16841 |
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/
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-10-28 17:05 +0100 |
| Message-ID | <1886339.7pA5ev5edD@PointedEars.de> |
| In reply to | #16921 |
Cezary Tomczyk wrote:
> 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.
Yes, you can.
>>>> 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.
Everybody makes mistakes; we can learn from them to make it better next
time. But making mistakes because of overlooking some detail, and making
mistakes because one does not know what they are doing in the first place,
are very different things. You *know* now that you have made a mistake by
either participating in a bad project, using a bad library, or both; not
correcting it now would be yet another mistake on your part.
>>>> 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.
This should be self-evident: There is no type conversion when both operands
are of the same type. See also ES 5.1, §11.9.
> 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 ===.
Delete JSHint.
> I wonder why this is required in our project by other developers?
I do not know. Perhaps because they cannot deal with type conversion as
they are used to statically and strictly typed languages? Very few people
actually understand these languages and their applications, which accounts
for a lot of bad code written in them.
> Correct me if I'm wrong, but if we know what type of object will be then
> there is no need to use ===, right?
No, it depends on the operands, and it depends on whether the operands are
object (reference)s to begin with. Neither a `typeof' operation nor
evaluating a string literal results in an object (reference).
>>>> {
>>>> 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 ?
Yes.
>>>>> 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?
Yes. The call may still fail in some cases, but you would have done your
best to prevent it. This is what defensive coding is about.
> 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.
So, assuming you are a responsible developer and a responsible person in
general, you should ask yourself: Why is this project using bad code now?
And why do you want to keep on using bad code in your project? Does that
not inevitably make *your* (project's) code bad code as well? Consider the
repercussions of (your) design decisions.
> 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.
I have already told you what your options are at this point:
A. You can stop using that library (and perhaps use a better one);
B. You can fix the library;
C. You can demand a fix from its author(s).
I do not think there are other options.
--
PointedEars
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-28 18:39 +0100 |
| Message-ID | <k6jqlh$nlb$1@speranza.aioe.org> |
| In reply to | #16923 |
W dniu 2012-10-28 17:05, Thomas 'PointedEars' Lahn pisze: > Cezary Tomczyk wrote: >>>>> 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. > > Everybody makes mistakes; we can learn from them to make it better next > time. But making mistakes because of overlooking some detail, and making > mistakes because one does not know what they are doing in the first place, > are very different things. You *know* now that you have made a mistake by That's why in my job I always asking other developers: "why did you do in that way?". If developer can explain in a clear way, I mean in that way I can understand, will provide me real example as a evidence and eventually source of algorithm (or idea) then working in that way for me is best optimized. > either participating in a bad project, using a bad library, or both; not > correcting it now would be yet another mistake on your part. Well, then there is at least few options: 1. Try to find the right people for change. 2. Accept the situation as it is and try to create a solution that will protect against errors of others. 3. Change project. 4. Build own project. >>>>> 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. > > This should be self-evident: There is no type conversion when both operands > are of the same type. See also ES 5.1, §11.9. I even extended little bit this test http://jsperf.com/typeof-equals-triple-double by comparing two different objects and IE9, Google Chrome 22.0.1229.94, Opera 12.02 for 4 tests are more or less similar, but Firefox 16.0.2 surprised me little bit: triple equals: 8167 Ops/sec double equals: 4752 Ops/sec triple equals - different objects: 90830 Ops/sec double equals - different objects: 89815 Ops/sec All of them tested on Windows 7, 64 bit. What a huge difference. Weird for me, little bit. >> 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 ===. > > Delete JSHint. Not all options are bad, I would say. Sometimes it prevent from a small, but very important bugs. >> Correct me if I'm wrong, but if we know what type of object will be then >> there is no need to use ===, right? > > No, it depends on the operands, and it depends on whether the operands are > object (reference)s to begin with. Neither a `typeof' operation nor > evaluating a string literal results in an object (reference). I thought about situation where both of operands are the same type. I've just reviewed my bookmarks and see nice article: http://dmitrysoshnikov.com/notes/note-2-ecmascript-equality-operators/#safe-cases-of-codecode. "The main thing which you should know that algorithms of == and === operator are completely equivalent, word-for-word, if types of operands are the same." >> 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. > > So, assuming you are a responsible developer and a responsible person in > general, you should ask yourself: Why is this project using bad code now? > And why do you want to keep on using bad code in your project? Does that > not inevitably make *your* (project's) code bad code as well? Consider the > repercussions of (your) design decisions. It's not my decision. It is required by project on which I'm co-working now. This project depend on 3-rd parties. Anyway, I've got your point, I understand and even know what consequences will be in the future, but let's no talk about situations that I cannot change. >> 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. > > I have already told you what your options are at this point: > > A. You can stop using that library (and perhaps use a better one); > B. You can fix the library; > C. You can demand a fix from its author(s). > > I do not think there are other options. For now I must work with option B (by wrapping bad methods with my custom methods as a temporary workaround) and count on fixes from point C. -- Cezary Tomczyk http://www.ctomczyk.pl/
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-10-28 20:10 +0100 |
| Message-ID | <270317591.RgZlF00zI7@PointedEars.de> |
| In reply to | #16927 |
Cezary Tomczyk wrote: > I even extended little bit this test > http://jsperf.com/typeof-equals-triple-double by comparing two different > objects and IE9, Google Chrome 22.0.1229.94, Opera 12.02 for 4 tests are > more or less similar, but Firefox 16.0.2 surprised me little bit: > > triple equals: 8167 Ops/sec > double equals: 4752 Ops/sec > triple equals - different objects: 90830 Ops/sec > double equals - different objects: 89815 Ops/sec > > All of them tested on Windows 7, 64 bit. > > What a huge difference. Weird for me, little bit. 1. You are benchmarking the wrong feature there. 2. I do not think you need loops with jsperf. 3. Never trust benchmarks. PointedEars -- Prototype.js was written by people who don't know javascript for people who don't know javascript. People who don't know javascript are not the best source of advice on designing systems that use javascript. -- Richard Cornford, cljs, <f806at$ail$1$8300dec7@news.demon.co.uk>
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2012-10-28 20:23 +0100 |
| Message-ID | <k6k0n0$8eb$1@speranza.aioe.org> |
| In reply to | #16932 |
W dniu 2012-10-28 20:10, Thomas 'PointedEars' Lahn pisze: > Cezary Tomczyk wrote: > >> I even extended little bit this test >> http://jsperf.com/typeof-equals-triple-double by comparing two different >> objects and IE9, Google Chrome 22.0.1229.94, Opera 12.02 for 4 tests are >> more or less similar, but Firefox 16.0.2 surprised me little bit: >> >> triple equals: 8167 Ops/sec >> double equals: 4752 Ops/sec >> triple equals - different objects: 90830 Ops/sec >> double equals - different objects: 89815 Ops/sec >> >> All of them tested on Windows 7, 64 bit. >> >> What a huge difference. Weird for me, little bit. > > 1. You are benchmarking the wrong feature there. Ok, maybe I should do two separate tests. > 2. I do not think you need loops with jsperf. Is there better way? > 3. Never trust benchmarks. Then one of the alternative is to measure time by using new Date().getTime() :/ -- Cezary Tomczyk http://www.ctomczyk.pl/
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2012-10-28 21:23 +0100 |
| Message-ID | <1626770.WBuXB4FIxE@PointedEars.de> |
| In reply to | #16933 |
Cezary Tomczyk wrote:
> W dniu 2012-10-28 20:10, Thomas 'PointedEars' Lahn pisze:
>> Cezary Tomczyk wrote:
>>> I even extended little bit this test
>>> http://jsperf.com/typeof-equals-triple-double by comparing two different
>>> objects and IE9, Google Chrome 22.0.1229.94, Opera 12.02 for 4 tests are
>>> more or less similar, but Firefox 16.0.2 surprised me little bit:
>>>
>>> triple equals: 8167 Ops/sec
>>> double equals: 4752 Ops/sec
>>> triple equals - different objects: 90830 Ops/sec
>>> double equals - different objects: 89815 Ops/sec
>>>
>>> All of them tested on Windows 7, 64 bit.
>>>
>>> What a huge difference. Weird for me, little bit.
>>
>> 1. You are benchmarking the wrong feature there.
>
> Ok, maybe I should do two separate tests.
You wanted to test `==' vs. `==='. What you are actually testing there is
`typeof ""' vs. `typeof {}'. Keep in mind that the `typeof' operation
*always* results in a string value.
>> 2. I do not think you need loops with jsperf.
>
> Is there better way?
Yes, omit them. jsperf loops by itself, and if it is any good it uses
nested loops.
>> 3. Never trust benchmarks.
>
> Then one of the alternative is to measure time by using new
> Date().getTime() :/
No, the reasonable alternative is to profile real code under real conditions
if and when slow speed becomes a problem. A V8 JavaScript profiler is
included in the Chromium/Chrome Developer Tools; Firebug contains one for
SpiderMonkey as well. Premature optimization is the root of all evil. [tm]
The issue of `==' vs. `===' is not so much speed; it is the outcome of
either operation, which can be unexpected in the former case.
PointedEars
--
Sometimes, what you learn is wrong. If those wrong ideas are close to the
root of the knowledge tree you build on a particular subject, pruning the
bad branches can sometimes cause the whole tree to collapse.
-- Mike Duffy in cljs, <news:Xns9FB6521286DB8invalidcom@94.75.214.39>
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.javascript
csiph-web