From: Thomas 'PointedEars' Lahn on
David Mark wrote:

> Garrett Smith wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> var reFeaturedMethod = new RegExp('^(function|object)$', 'i');
>>
>> A Literal would be shorter and would stay cached:
>>
>> /^(?:func|obj)/;
>
> I fail to see how that is the same thing, but the non-capturing bit is a
> good idea.

Not if you want this to be backwards-compatible. The Matrix says:

ES JavaScript JScript V8 JSCore Opera KJS
/(?:…)/ : RegExp 3 1.5 5.5.6330 1.3 525.13 7.02 3.5.9

> As for caching, I don't see how it makes any difference as I create the
> RegExp object once.

The question is moot anyway since ES5 implementations instantiate a new
object each time they encounter the literal. (This is different in ES3.)

>>> Furthermore, AISB,
>>>
>>> return !!((reFeaturedMethod.test(t) && o[m]) || t == 'unknown');
>>>
>>> becomes more efficient when writing
>>>
>>> return !!(t == 'unknown' || (reFeaturedMethod.test(t) && o[m]));
>>>
>>> The double negation to cast to boolean is a matter of taste; I do not
>>> think it is necessary, because one possible result is a boolean
>>> already and the other has been proven by this that it can be used in a
>>> type-converting test.
>>
>> Double negation on a boolean is pointless.

Yes.

>> However, `o[m]` should not be a boolean; it should be a function or an
>> object.

I beg your pardon?

> Right.

return (t == 'unknown' || (reFeaturedMethod.test(t) && !!o[m]));

But AISB the `!!' does not really save anything as in a boolean context the
return value would be subject to type conversion anyway.

>> Caveats:
>> Object `o` could be callable and falsish, such as nonstandard callable
>> "document.all".

Is there a good reason for document.all(...) instead of document.all[...]?
If not, that fact is largely irrelevant.

>> Object `o` could be the `item` method, for which typeof will result
>> "string" in IE. This would result in isHostMethod returning false.
>
> Yes, I should add both of those stipulations to the docs and this
> example.

That argument only makes sense if _o[m]_ refers to the item() method of
NodeList or HTMLCollection implementations. Then again, is there a good
reason to call o.item(i) instead of accessing o[i]? If not, that fact is
largely irrelevant.


PointedEars
--
Danny Goodman's books are out of date and teach practices that are
positively harmful for cross-browser scripting.
-- Richard Cornford, cljs, <cife6q$253$1$8300dec7(a)news.demon.co.uk> (2004)
From: David Mark on
Thomas 'PointedEars' Lahn wrote:
> David Mark wrote:
>
>> Garrett Smith wrote:
>>> Thomas 'PointedEars' Lahn wrote:
>>>> var reFeaturedMethod = new RegExp('^(function|object)$', 'i');
>>> A Literal would be shorter and would stay cached:
>>>
>>> /^(?:func|obj)/;
>> I fail to see how that is the same thing, but the non-capturing bit is a
>> good idea.
>
> Not if you want this to be backwards-compatible. The Matrix says:
>
> ES JavaScript JScript V8 JSCore Opera KJS
> /(?:…)/ : RegExp 3 1.5 5.5.6330 1.3 525.13 7.02 3.5.9

I wasn't sure about that, which is why I tend to stick with what I know
for sure. Thanks for illuminating that. Verboten for My Library.

>
>> As for caching, I don't see how it makes any difference as I create the
>> RegExp object once.
>
> The question is moot anyway since ES5 implementations instantiate a new
> object each time they encounter the literal. (This is different in ES3.)

Interesting. What possessed them to do that?

>
>>>> Furthermore, AISB,
>>>>
>>>> return !!((reFeaturedMethod.test(t) && o[m]) || t == 'unknown');
>>>>
>>>> becomes more efficient when writing
>>>>
>>>> return !!(t == 'unknown' || (reFeaturedMethod.test(t) && o[m]));
>>>>
>>>> The double negation to cast to boolean is a matter of taste; I do not
>>>> think it is necessary, because one possible result is a boolean
>>>> already and the other has been proven by this that it can be used in a
>>>> type-converting test.
>>> Double negation on a boolean is pointless.
>
> Yes.
>
>>> However, `o[m]` should not be a boolean; it should be a function or an
>>> object.
>
> I beg your pardon?

o[m] will not normally be a boolean, hence the double negation.

>
>> Right.
>
> return (t == 'unknown' || (reFeaturedMethod.test(t) && !!o[m]));
>
> But AISB the `!!' does not really save anything as in a boolean context the
> return value would be subject to type conversion anyway.

That's true. But I prefer to have the function return booleans only.

>
>>> Caveats:
>>> Object `o` could be callable and falsish, such as nonstandard callable
>>> "document.all".
>
> Is there a good reason for document.all(...) instead of document.all[...]?
> If not, that fact is largely irrelevant.

I missed that that second part was mentioned. I already mentioned about
the sometimes callable objects in the explanation and documentation.
Don't request an opinion from isHostMethod on those.

>
>>> Object `o` could be the `item` method, for which typeof will result
>>> "string" in IE. This would result in isHostMethod returning false.
>> Yes, I should add both of those stipulations to the docs and this
>> example.
>
> That argument only makes sense if _o[m]_ refers to the item() method of
> NodeList or HTMLCollection implementations. Then again, is there a good
> reason to call o.item(i) instead of accessing o[i]? If not, that fact is
> largely irrelevant.
>

Right. It is odd that the one exception to an otherwise golden rule is
something you would/should never need anyway. Still, it's an
interesting caveat and I think I will mention it.
From: kangax on
On 3/23/10 6:00 PM, David Mark wrote:
> kangax wrote:
>> On 3/23/10 12:52 PM, David Mark wrote:
>>> I have posted a new primer related to host objects and feature
>>> detection/testing.
>>>
>>> http://www.cinsoft.net/host.html
>>
>> Is there a reason `isHostObjectProperty` is not called `isHostProperty`
>> (to be consistent with `isHostMethod`)?
>
> The "Object" goes with "Property", not the "Host" part.

I understand that :) But what does "Property" clarify there? What's
wrong with having `isHostMethod` and `isHostProperty` � where first one
is for testing anything that's intended to be called (i.e. method), and
latter � for anything that won't be called (i.e. property).

[...]

>>
>> Finally, it might be worth mentioning that `isEventSupported` could (and
>> _does_, as any other inference) return false positives; from those I
>> know about � `window`'s "error" in Chrome (present but "defunct"), and
>> "contextmenu" in Opera 10.50 (even when corresponding option is off in
>> settings!).
>
> It is only meant to be used with elements (which I should stipulate of
> course). As for "contextmenu", I never considered that a false
> positive. The event is supported, but like many things in browsers, the
> user has the ability to get in the way. But from your wording, it
> sounds as if there is a bug in Opera 10.5 that should be noted (and
> reported).

Yeah, I should report it to them. The fact that Opera bug tracker is not
open is annoying (I have no idea what's going on with the bugs I filed
in the past).

--
kangax
From: Garrett Smith on
David Mark wrote:
> Garrett Smith wrote:
>> Thomas 'PointedEars' Lahn wrote:
>>> David Mark wrote:
>>>
>>>> I have posted a new primer related to host objects and feature
>>>> detection/testing.
>> [...]
>>
>>> ISTM the RegExp is borken:
>>>
>>> var reFeaturedMethod = new RegExp('^function|object$', 'i');
>>>
>>> It matches case-insensitive either "function" at the begin of input or
>>> "object" at the end, when it should match case-insensitive an input
>>> that is either "function" or "object":
>>>
>>> var reFeaturedMethod = new RegExp('^(function|object)$', 'i');
>>>
>> A Literal would be shorter and would stay cached:
>>
>> /^(?:func|obj)/;
>
> I fail to see how that is the same thing, but the non-capturing bit is a
> good idea.
>
It is not the same thing.

Either would do the job as well as:
/^(?:function|object)$/;

Being case-insensitive is pointless, though. I'd ditch the 'i' flag
either way.

> As for caching, I don't see how it makes any difference as I create the
> RegExp object once.
>

The difference would be when the object is created. Either at runtime
(as with constructor) or during lexical scan for regexp literal.
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/
From: Garrett Smith on
David Mark wrote:
> Garrett Smith wrote:
>> David Mark wrote:
>>> I have posted a new primer related to host objects and feature
>>> detection/testing.
>>>
>>> http://www.cinsoft.net/host.html
>>>
>> | The isHostObjectProperty function tests if the specified host object
>> | property references an object that is safe to evaluate.
>>
>> The term "evaluate" is non-standard terminology. What do you mean?
>
> Anything along the lines of type conversion, assigning a reference to a
> variable, etc. What would you call it?

I like to see the standard terminology to describe the problems.
I mentioned a few of the problems with host objects here:

http://jibbering.com/faq/notes/code-guidelines/#hostObjects

Posted inline, for convenience:
| Host Objects:
|
| * Operators:
| o Do not use delete operator with host object (IE Errors)
| o Do not add any expando properties (unselectable is safe)
| o Host objects that error upon [[Get]] access are often ActiveX
| objects. These include, but are not limited to:
| + Disconnected nodes whose parentNode is not an element
| (node.offsetParent)
| + XMLHttpRequest methods (open, send, etc).
| + filters: elem.filters.alpha, elem.style.filters.alpha, etc.
| + document.styleSheets[99999] - Error from [[Get]] for a
| nonexistent numeric property of a styleSheets collection.
| + link.href for nntp: links in IE.
| + NodeList in Safari 2 - do not attempt access a nonexistent
| property (e.g. document.childNodes.slice).
|
| * Type conversion
| [[ToString]]
| Perform string conversion by starting concatenation with a string
| value. See Newsgroup message explanation.
<URL:
http://groups.google.bg/group/comp.lang.javascript/msg/1528f612e31f09fe >
--
Garrett
comp.lang.javascript FAQ: http://jibbering.com/faq/