473,385 Members | 1,531 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

When is a function not a function?

I've got a collection of functions that accept a function or object
(paired with a method name) as a callback.

For the longest time I have relied on this test.

(typeof cb == 'function')

This should work as well, but I am not sure how well it degrades in
older browsers. I think there are issues with functions created in
another context (eg frame) as well.

(cb instanceof Function)

Then I came across this.

(!!fn && typeof fn != "string" && !fn.nodeName && fn.constructor !=
Array && /function/i.test( fn + "" ))

I'm sure it is wrong as it is from jQuery, but it makes me wonder if
there are bugs in older browsers that will mislead my test.

As an aside, I was looking at the jQuery source as some browser
sniffer I was arguing with on a blog cited it as part of an "everybody
is doing it" argument. I had glanced at it previously and dismissed
it based on its resemblance to Prototype. Upon closer inspection, it
makes Prototype look inspired. Suffice to say that anybody who
recommends it hasn't read the code. It's a horror show.

Sep 26 '07 #1
32 3457
On Sep 25, 7:09 pm, David Mark <dmark.cins...@gmail.comwrote:
I've got a collection of functions that accept a function or object
(paired with a method name) as a callback.

For the longest time I have relied on this test.

(typeof cb == 'function')

This should work as well, but I am not sure how well it degrades in
older browsers. I think there are issues with functions created in
another context (eg frame) as well.

(cb instanceof Function)

Then I came across this.

(!!fn && typeof fn != "string" && !fn.nodeName && fn.constructor !=
Array && /function/i.test( fn + "" ))

I'm sure it is wrong as it is from jQuery, but it makes me wonder if
there are bugs in older browsers that will mislead my test.
I don't like to assume incorrect because it is in jQuery. I am
surprised if they are testing in older browsers. The hip libraries
don't seem to do that.

As an aside, I was looking at the jQuery source as some browser
sniffer I was arguing with on a blog cited it as part of an "everybody
is doing it" argument. I had glanced at it previously and dismissed
it based on its resemblance to Prototype. Upon closer inspection, it
makes Prototype look inspired. Suffice to say that anybody who
recommends it hasn't read the code. It's a horror show.
In a talk at Google, John Resig, jQuery founder, said something like
"after fighting with browser bugs long enough an experienced
JavaScript program just uses navigator.userAgent." At least that is
how I understood his talk. He does say many really good things. You
can watch the video.

http://ejohn.org/blog/building-a-javascript-library/

I left a comment on that blog page about sniffing and he never did
really respond. Perhaps that future blog post to which he refers later
in the comments is still in the works. I'm interested to read it.

Tricky one: How do you feature test opacity support?

Peter

Sep 26 '07 #2
On Sep 26, 1:02 pm, David Mark <dmark.cins...@gmail.comwrote:
jQuery uses dollar sign variables, which I don't think are allowed
under the specification.
Dollar signs are allowed. See sec 7.6. The spec then says "The dollar
sign is intended for use only in mechanically generated code."

After reading all the uproar about dollar signs in variables or even
one character dollar sign variable, I think it would have been better
if they had left this statement of intention out of the spec. A dollar
sign can or cannot be in an identifier. If it can then it is up to the
programmer to decide how to use it. If I was writing JavaScript to
last 100 years and knew JavaScript would be backwards compatible with
the exception of new keywords, I would probably start all my
identifiers with a dollar sign (eg. $foo, $bar) to avoid clashes with
new keywords.

Peter

Sep 26 '07 #3
On Sep 26, 5:22 pm, Peter Michaux <petermich...@gmail.comwrote:
On Sep 26, 1:02 pm, David Mark <dmark.cins...@gmail.comwrote:
jQuery uses dollar sign variables, which I don't think are allowed
under the specification.

Dollar signs are allowed. See sec 7.6. The spec then says "The dollar
sign is intended for use only in mechanically generated code."
I understand that, but I don't think the authors of these libraries
are robots.
>
After reading all the uproar about dollar signs in variables or even
one character dollar sign variable, I think it would have been better
if they had left this statement of intention out of the spec. A dollar
sign can or cannot be in an identifier. If it can then it is up to the
programmer to decide how to use it. If I was writing JavaScript to
last 100 years and knew JavaScript would be backwards compatible with
the exception of new keywords, I would probably start all my
identifiers with a dollar sign (eg. $foo, $bar) to avoid clashes with
new keywords.
The biggest problem I have is naming functions "$" or "$$" or anything
like that. If you minify your production code then the only argument
for these is to reduce the total number of keystrokes required to
write a script. Apparently these people have never heard of macros.

Sep 26 '07 #4
Peter Michaux wrote:
On Sep 26, 1:02 pm, David Mark <dmark.cins...@gmail.comwrote:
>jQuery uses dollar sign variables, which I don't think are allowed
under the specification.

Dollar signs are allowed. See sec 7.6. The spec then says "The dollar
sign is intended for use only in mechanically generated code."
Which is exactly why jQuery should not.
After reading all the uproar about dollar signs in variables or even
one character dollar sign variable, I think it would have been better
if they had left this statement of intention out of the spec. A dollar
sign can or cannot be in an identifier.
This subsection addresses only identifiers. You missed the point completely.
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Sep 26 '07 #5
Peter Michaux wrote:
[...] "Richard Cornford" [...] wrote:
>Peter Michaux wrote:
>>If I was writing JavaScript to last 100 years and knew
JavaScript would be backwards compatible with the exception
of new keywords, I would probably start all my identifiers
with a dollar sign (eg. $foo, $bar) to avoid clashes with
new keywords.
Doesn't that imply that given a sufficiently long period of time a
programming language will grow an infinite number of keywords?

I don't think I implied that. By using $ at the start of every one of
my identifiers, I'm protected from that one new keyword that clashes.
Generally, you are not. There are built-in properties that begin with `$'.
Hence "machine-generated".
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Sep 27 '07 #6
Thomas 'PointedEars' Lahn said the following on 9/26/2007 5:40 PM:
Peter Michaux wrote:
>On Sep 26, 1:02 pm, David Mark <dmark.cins...@gmail.comwrote:
>>jQuery uses dollar sign variables, which I don't think are allowed
under the specification.
Dollar signs are allowed. See sec 7.6. The spec then says "The dollar
sign is intended for use only in mechanically generated code."

Which is exactly why jQuery should not.
But there is no reason why it *can not* other than people's pedantic
desires to whine about it. Had it been S that was used instead, people
would shut up about it and move on. Except that if it had been S instead
of $ then people would be whining about how the name wasn't an
indication of what it did.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Sep 27 '07 #7
On Sep 26, 5:39 pm, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
Generally, the place for one letter Identifiers is as local variable
names in functions that are sufficiently small that their declarations
and all of their uses can be simultaneously surveyed. And maybe not even
then.

I find it's odd that the Prototype folks like very short API
identifiers but use very long local variable names inside Prototype.

Peter

Sep 27 '07 #8
On Sep 26, 4:38 pm, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
Peter Michaux wrote:
On Sep 26, 1:02 pm, David Mark wrote:
jQuery uses dollar sign variables, which I don't think are
allowed under the specification.
Dollar signs are allowed. See sec 7.6. The spec then says
"The dollar sign is intended for use only in mechanically
generated code."

The same is true for Java (indeed it appears that the idea of making
provision for a conventional form to exist for machine generated code
was inspired by the similar convention in Java). You never see Java
programmers using $ symbols in their code, even though not doing so is
no more than a convention. A Java programmer who disregarded that
convention would be derided, but unfortunately a sufficiently large
proportion of javascript 'programmers' are unprofessional (in every
sense of the world) that these faults can seem tolerable.
After reading all the uproar about dollar signs in variables
or even one character dollar sign variable, I think it would
have been better if they had left this statement of intention
out of the spec.

In that case it would have been better to leave the $ symbol out of the
set of acceptable characters for an Identifier.
A dollar sign can or cannot be in an identifier.

Just as it can in Java.
If it can then it is up to the programmer to decide how
to use it.

Just as it is for Java programmers, but they have more understanding of
their specification, and more appreciation for the value of conventions
in programming.
So Java programmers are all instances of the same class?

Peter

Sep 27 '07 #9
On Wed, 26 Sep 2007 at 20:21:44, in comp.lang.javascript, Randy Webb
wrote:
>Thomas 'PointedEars' Lahn said the following on 9/26/2007 5:40 PM:
>Peter Michaux wrote:
>>On Sep 26, 1:02 pm, David Mark <dmark.cins...@gmail.comwrote:
jQuery uses dollar sign variables, which I don't think are allowed
under the specification.
Dollar signs are allowed. See sec 7.6. The spec then says "The dollar
sign is intended for use only in mechanically generated code."
Which is exactly why jQuery should not.

But there is no reason why it *can not* other than people's pedantic
desires to whine about it. Had it been S that was used instead, people
would shut up about it and move on. Except that if it had been S
instead of $ then people would be whining about how the name wasn't an
indication of what it did.

But it's already happened :

Thou shalt not start a global name with "MM_".

Because otherwise there will come a day when you get an obscure bug that
will drive you crazy.

There's a similar rule in C++ about names starting with leading
underlines. The difference is that the rule has been biting people for
years, so competent programmers don't dismiss it as pedantic standards
mania.

John
--
John Harris
Sep 27 '07 #10
John G Harris said the following on 9/27/2007 3:37 PM:
On Wed, 26 Sep 2007 at 20:21:44, in comp.lang.javascript, Randy Webb
wrote:
>Thomas 'PointedEars' Lahn said the following on 9/26/2007 5:40 PM:
>>Peter Michaux wrote:
On Sep 26, 1:02 pm, David Mark <dmark.cins...@gmail.comwrote:
jQuery uses dollar sign variables, which I don't think are allowed
under the specification.
Dollar signs are allowed. See sec 7.6. The spec then says "The dollar
sign is intended for use only in mechanically generated code."
Which is exactly why jQuery should not.
But there is no reason why it *can not* other than people's pedantic
desires to whine about it. Had it been S that was used instead, people
would shut up about it and move on. Except that if it had been S
instead of $ then people would be whining about how the name wasn't an
indication of what it did.


But it's already happened :

Thou shalt not start a global name with "MM_".
Or __, ever heard of __doPostBack and the others? All of which are
naming clashes.
Because otherwise there will come a day when you get an obscure bug that
will drive you crazy.
That is true with any prefix though. Not just $ or MM or __
There's a similar rule in C++ about names starting with leading
underlines. The difference is that the rule has been biting people for
years, so competent programmers don't dismiss it as pedantic standards
mania.
Nice to know that about C++ but I don't see the relationship between C++
and/or Java (that Richard brought into it).

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Sep 27 '07 #11
dh**********@gmail.com wrote:
On Oct 3, 9:59 am, Randy Webb <HikksNotAtH...@aol.comwrote:
>Richard Cornford said the following on 9/30/2007 4:36 PM:
>>Randy Webb wrote:
>It doesn't say "limited" or "required". It simply says "This is what it
is *intended* for". I doubt very seriously that 99% of what is done with
scripting was it's "intended use".

Either way, it doesn't matter what ECMA had to say about it, people are
still going to use it until some UA comes out that breaks it. And no
amount of discussing it in comp.lang.javascript will ever change that.

Things that might seem not to matter:
{OOA&D, Testing, Variable names, comments, code formatting
conventions, process}

These things are just not that appealing to people, generally. This is
especially true for presentation layer development. Why not look at
what toolkit vendors do? They're the rock stars, right?

Yahoo still employs code freezes, status reports, and last time I was
there, my manager would not let me check ANY tests into CVS (they
still don't use SVN). They were calling this Scrum.

Little things like "don't use post-increment operator" are easy for
people to grasp. Free advice that comes with cookies and refreshments.
Serotonin levels go up with the increased blood sugar, jokes are told,
examples are shown (with much hand waving), and people are happy while
not working.

I do wonder though: Why $? I would like to know, out of curiosity, why
did jQuery use $? There is a reason the variable was used; I just
don't know what it is.

I would say ha about 90% of "standards" s not so much 'best practice' as
just plain simple 'do it this ways so that people coming upon you
unexpectedly will know what's going on'

E.g. we all drive on one side of the road, but which side is open to debate.

Standards are there mostly for people working together, to enforce a
common style, so everybody knows how things should be done.

Its a mark of the petty jobsworth to elect such standards into moral Laws.
>--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ -http://jibbering.com/faq/index.html
Javascript Best Practices -http://www.JavascriptToolbox.com/bestpractices/

Oct 5 '07 #12
dh**********@gmail.com wrote:
I do wonder though: Why $? I would like to know, out of curiosity, why
did jQuery use $? There is a reason the variable was used; I just
don't know what it is.
Cluelessness. (That was easy.)
PointedEars
--
"Use any version of Microsoft Frontpage to create your site. (This won't
prevent people from viewing your source, but no one will want to steal it.)"
-- from <http://www.vortex-webdesign.com/help/hidesource.htm>
Oct 5 '07 #13
Thomas 'PointedEars' Lahn said the following on 10/5/2007 9:14 AM:
dh**********@gmail.com wrote:
>I do wonder though: Why $? I would like to know, out of curiosity, why
did jQuery use $? There is a reason the variable was used; I just
don't know what it is.

Cluelessness. (That was easy.)
And it is debatable who is the one possessing the "Cluelessness".

Why it was used is trivial to figure out.

P.S. YSCIB

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Oct 5 '07 #14
Randy Webb wrote:
Thomas 'PointedEars' Lahn said the following on 10/5/2007 9:14 AM:
>dh**********@gmail.com wrote:
>>I do wonder though: Why $? I would like to know, out of curiosity, why
did jQuery use $? There is a reason the variable was used; I just
don't know what it is.
Cluelessness. (That was easy.)

And it is debatable who is the one possessing the "Cluelessness".
Not understood.
Why it was used is trivial to figure out.
Then you can tell it for sure, yes?
P.S. YSCIB
-v
PointedEars
--
var bugRiddenCrashPronePieceOfJunk = (
navigator.userAgent.indexOf('MSIE 5') != -1
&& navigator.userAgent.indexOf('Mac') != -1
) // Plone, register_function.js:16
Oct 5 '07 #15
Thomas 'PointedEars' Lahn said the following on 10/5/2007 7:37 PM:
Randy Webb wrote:
>Thomas 'PointedEars' Lahn said the following on 10/5/2007 9:14 AM:
>>dh**********@gmail.com wrote:
I do wonder though: Why $? I would like to know, out of curiosity, why
did jQuery use $? There is a reason the variable was used; I just
don't know what it is.
Cluelessness. (That was easy.)
And it is debatable who is the one possessing the "Cluelessness".

Not understood.
Try enabling the spell checker in Thunderbird. It might shed some light
on it.
>Why it was used is trivial to figure out.

Then you can tell it for sure, yes?
Sure I can. It was chosen because of the uniqueness of it and the lack
of use of it on the web. What better way to pick a simple single
character identifier than one that wasn't in use?

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Oct 6 '07 #16
Randy Webb wrote:
Thomas 'PointedEars' Lahn said the following on 10/5/2007 7:37 PM:
>Randy Webb wrote:
>>Thomas 'PointedEars' Lahn said the following on 10/5/2007 9:14 AM:
dh**********@gmail.com wrote:
I do wonder though: Why $? I would like to know, out of curiosity, why
did jQuery use $? There is a reason the variable was used; I just
don't know what it is.
Cluelessness. (That was easy.)
And it is debatable who is the one possessing the "Cluelessness".
Not understood.

Try enabling the spell checker in Thunderbird. It might shed some light
on it.
It merely shows that you don't know the word and that it isn't in the
default dictionary of Thunderbird's spell checker.
>>Why it was used is trivial to figure out.
Then you can tell it for sure, yes?

Sure I can.
You can *not*, you are not the author.
It was chosen because of the uniqueness of it and the lack
of use of it on the web.
Logical fallacy: wishful thinking. You can know neither whether or not it
was used on the Web at the time the library was conceived, nor can you know
that supposed uniqueness or supposed no-use at the time was the reason for
choosing it.
What better way to pick a simple single character identifier than one
that wasn't in use?
Logical fallacy: non sequitur.
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, <f8*******************@news.demon.co.uk>
Oct 6 '07 #17
Thomas 'PointedEars' Lahn said the following on 10/6/2007 7:53 AM:
Randy Webb wrote:
>Thomas 'PointedEars' Lahn said the following on 10/5/2007 7:37 PM:
>>Randy Webb wrote:
Thomas 'PointedEars' Lahn said the following on 10/5/2007 9:14 AM:
dh**********@gmail.com wrote:
>I do wonder though: Why $? I would like to know, out of curiosity, why
>did jQuery use $? There is a reason the variable was used; I just
>don't know what it is.
Cluelessness. (That was easy.)
And it is debatable who is the one possessing the "Cluelessness".
Not understood.
Try enabling the spell checker in Thunderbird. It might shed some light
on it.

It merely shows that you don't know the word and that it isn't in the
default dictionary of Thunderbird's spell checker.
<eyerollYou still don't get it. I didn't expect you to though.
>>>Why it was used is trivial to figure out.
Then you can tell it for sure, yes?
Sure I can.

You can *not*, you are not the author.
You need to get out into the real world more often Thomas.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Oct 6 '07 #18
dh**********@gmail.com wrote:
On Oct 13, 2:41 am, Thomas 'PointedEars' Lahn <PointedE...@web.de>
wrote:
>The code comes from jQuery (1.2.1):

// This may seem like some crazy code, but trust me when I say that this
// is the only cross-browser way to do this. --John
isFunction:function( fn ) {
return !!fn && typeof fn != "string" && !fn.nodeName &&
fn.constructor != Array && /function/i.test( fn + "" );
}

jQuery claims to support IE 6.0+, FF 1.5+, Safari 2.0+, Opera 9.0+ (and
calls that "cross-browser" -- OMG). But, if

/function/i.test(fn + "")

would return `true', it is highly unlikely that

typeof fn

would yield "string", so the test

typeof fn != "string"

is unnecessary. Unless, of course, someone who lacks the minimum clue
assumes that strings could be called and so could ever be subject to
isFunction().

No, it excludes strings.
Which is unnecessary, as strings could never be called, and so should never
be subject to the isFunction() test method.
"function" + "" would return true. This clause prevents that.
But can you name a case where a callable object would evaluate as a string
containing "function" without type conversion?
>Furthermore, if

/function/i.test(fn + "")

would return `true', how could it be that

fn.constructor != Array

var a = Array{function bork(){});
But that assumes that `a' could be called which it cannot be. Hence it
should not be subject to an isFunction() test. An array is not a function.
>couldnotyield `true'
Again, I did not write it that way. Please stop using broken software.
and therefore that test would be unnecessary as well?
No.
Yes.
>Needless to say that RegExp.prototype.test() already type-converts its
argument to string (see ECMAScript Ed. 3, 15.10.6.3) and so the forced
conversion by concatenation is unnecessary.

That's true, but being explicit is a good thing.
Being explicit would be

/.../.test(String(...))

But that would be nonsense as well, as it would decrease efficiency.
Because if the specification algorithm is followed, type conversion
to String would happen *twice* in both cases: first due to the source
code and the second time as step 1 of RegExp.prototype.exec().
>And aFunctionobject, being a native object, certainly could have a
user-defined property `nodeName' and still could be called. So that
test makes no sense as well.

Right, so could any of the four examples on my site.
I didn't care about your (Web?) site and I have no intention to do so. If
you have arguments to present, please do it here.
>- False-values could only yield `object', as `null' does, but they wouldnot
type-convert to `true';

- typeof fn == "string" is already excluded (unless one assumes the
improbable case that `typeof' would yield "stringfunction" and the like);

new String()
{toString:function(){return 'function';}}
This is assuming that a String object could be called and so should/could
ever be subject to isFunction().
a = Function();
a.toString = "widget";
What should this accomplish? Overwriting the toString() method with a
string value renders type conversion to string non-functional. And even
if you meant

a = Function();
a.toString = function() { return "widget"; };

`typeof a' still would yield "function". The flaw in the described
algorithm is that it does not use `typeof' first. Because if it did,
many tests would not be necessary and the algorithm as a whole would
be less obscure and less error-prone.
>- fn.constructor != Array could only yield `true' because typeof "function"
would apply;

frames.
I don't see any argument here.
String values do not imply an object's type. Relying on toString is
not safe.
Exactly.
PointedEars
Oct 14 '07 #19
Randy Webb wrote:
Richard Cornford said the following on 10/14/2007 11:18 AM:
>Randy Webb wrote:
>>Richard Cornford said the following on 10/13/2007 10:28 PM:
<dh**********@gmail.comwrote:
typeof fn? nope, not in safari.
Are you certain? Is it really the case that objects that
return 'function' from a typeof operation cannot be
called? Or are you just not expecting them to be callable?
Have you actually tried calling the objects that safari
asserts are functions?
Can I ask you to first define what you mean by "called"
or "callable"?
No more than sticking an ArgumentsList after a reference to the object
(the 'call operator', with or without arguments). That is what I would
consider calling an object, and to be callable that abject should not
throw an exception as a direct result of its being called (though it may
still throw an exception in response to its arguments'' values, as that
would be behaviour passed the point of calling it and so unrelated to
its callability).

That would imply, to me anyway, that Safari (even in Beta form) gets it
right and all other browsers I tested it on get it wrong. Would that be
a correct assumption?
Not at all. With host objects, all bets are off. And as long as objects
that can't be called do not yield `function' or `object', there is no problem.
>>All other Windows based browsers I have report it as 'object'.
Maybe, but that is neither necessarily true of windows based browsers
nor historically common on Mac browsers. Even Mac IE 5 would report
'function' in this context, and on Windows you only have to go back a
few Opera versions to see the same there.

Then Safari is right and IE/FF/Opera are wrong?
It is not a matter of right and wrong.
PointedEars
--
realism: HTML 4.01 Strict
evangelism: XHTML 1.0 Strict
madness: XHTML 1.1 as application/xhtml+xml
-- Bjoern Hoehrmann
Oct 14 '07 #20
Thomas 'PointedEars' Lahn said the following on 10/14/2007 2:00 PM:
Randy Webb wrote:
>Richard Cornford said the following on 10/14/2007 11:18 AM:
>>Randy Webb wrote:
Richard Cornford said the following on 10/13/2007 10:28 PM:
<dh**********@gmail.comwrote:
>typeof fn? nope, not in safari.
Are you certain? Is it really the case that objects that
return 'function' from a typeof operation cannot be
called? Or are you just not expecting them to be callable?
Have you actually tried calling the objects that safari
asserts are functions?
Can I ask you to first define what you mean by "called"
or "callable"?
No more than sticking an ArgumentsList after a reference to the object
(the 'call operator', with or without arguments). That is what I would
consider calling an object, and to be callable that abject should not
throw an exception as a direct result of its being called (though it may
still throw an exception in response to its arguments'' values, as that
would be behaviour passed the point of calling it and so unrelated to
its callability).
That would imply, to me anyway, that Safari (even in Beta form) gets it
right and all other browsers I tested it on get it wrong. Would that be
a correct assumption?

Not at all. With host objects, all bets are off. And as long as objects
that can't be called do not yield `function' or `object', there is no problem.
Is there any thing in scripting that isn't an Object though? That part
is confusing to me. I thought any and everything was an Object, at least
underneath, and that functions were merely augmented Objects. That
implies to me that anything and everything should return object or some
subset of object.
>>>All other Windows based browsers I have report it as 'object'.
Maybe, but that is neither necessarily true of windows based browsers
nor historically common on Mac browsers. Even Mac IE 5 would report
'function' in this context, and on Windows you only have to go back a
few Opera versions to see the same there.
Then Safari is right and IE/FF/Opera are wrong?

It is not a matter of right and wrong.
Thank you.

--
Randy
Chance Favors The Prepared Mind
comp.lang.javascript FAQ - http://jibbering.com/faq/index.html
Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
Oct 14 '07 #21
Randy Webb wrote:
Richard Cornford said the following on 10/14/2007 11:18 AM:
>Randy Webb wrote:
<snip>
>>Can I ask you to first define what you mean by "called"
or "callable"?

No more than sticking an ArgumentsList after a reference to
the object (the 'call operator', with or without arguments).
That is what I would consider calling an object, and to be
callable that abject should not throw an exception as a direct
result of its being called (though it may still throw an
exception in response to its arguments'' values, as that would be
behaviour passed the point of calling it and so
unrelated to its callability).

That would imply, to me anyway, that Safari (even in Beta form)
gets it right
It is more a matter of what safari is doing is not in any way incorrect.
It could do much else instead and still not be doing anything incorrect.
Generally I am inclined to think that when at object can be called it
makes perfect sense for - typeof - to report 'function', even if with
host objects there is nothing to say that they should.
and all other browsers I tested it on get it wrong.
They are not getting it wrong, as there is nothing to define what would
qualify as 'correct' in this context. Some of those browsers are doing
something that is a little irrational in having a callable object but
reporting 'object' with - typeof -, but they either are Windows IE or
are imitating Windows IE in some of its more irrational behaviour.

Remember that on Windows IE all the DOM methods, and functions such as
alert and setTimeout also report 'object' from - typeof -, so it is at
least consistently irrational.
Would that be a correct assumption?
There are no grounds for expecting any particular outcome so there are
no criteria for correct or incorrect.

<snip>
>>All other Windows based browsers I have report it as
'object'.

Maybe, but that is neither necessarily true of windows based
browsers nor historically common on Mac browsers. Even Mac
IE 5 would report 'function' in this context, and on Windows
you only have to go back a few Opera versions to see the same
there.

Then Safari is right and IE/FF/Opera are wrong?
<snip>

On firefox (and all previous Mozilla/gecko browsers) you could not call
the collection objects, so reporting 'object' from - tyepof - is a
rational action. Windows IE is just doing the same as it always has
done, and Opera has recently changed to imitate the behaviour of Windows
IE (previously it did report 'function'). I don't approve of that change
but I can understand why it has happened.

Richard.

Oct 14 '07 #22
Thomas 'PointedEars' Lahn wrote:
Randy Webb wrote:
>and that functions were merely augmented Objects.

Functions/methods are special objects that can be called and inherit from
Object.prototype.
D'oh. Make that Function.prototype.
Oct 14 '07 #23
On Oct 14, 11:18 am, "Richard Cornford" <Rich...@litotes.demon.co.uk>
wrote:
[snip]
>
This is the dojo function:-

| if(dojo.isBrowser && dojo.isSafari){
| // only slow this down w/ gratuitious casting in Safari since
| // it's what's b0rken
| dojo.isFunction = function(/*anything*/ it){
| if((typeof(it) == "function") && (it == "[object NodeList]")){
| return false;
| }
| return (typeof it == "function" || it instanceof Function);
| }
| }else{
| dojo.isFunction = function(/*anything*/ it){
| return (typeof it == "function" || it instanceof Function);
| }
| }
It is useful to note that Dojo (along with jQuery) was cited as an
example of a "major library" that implements browser sniffing, in a
misguided attempt to justify browser sniffing as a viable technique.

Clearly the author(s) have assumed that Safari is the only agent that
is "b0rken" in this way (and that their isSafari method is a reliable
indication of a Safari browser.) As noted, the forks that follow
raise questions about what this code is supposed to do. It also casts
serious doubt about the veracity of functions built atop it.

So the browser sniffer who cited this mess as an example is justifying
his own incompetence by comparing it to other peoples' less-than-
competent output. The fact that lots of developers use these
libraries is cited as proof that they are a worthwhile comparison.
The "argument" is circular as users of jQuery, Dojo, Prototype, etc.
know only what they hear from the "experts" who churn out the
libraries. The "experts" conclude that since so many less-than-expert
developers listen to them, they must be on the right track. Tell
either side they are wrong and they cite the other.

Oct 15 '07 #24
Matt Kruse wrote:
On Oct 14, 9:18 am, Richard Cornford wrote:
>Fist you must state what it is that defined 'a function'. One
completely rational and justifiable definition of 'a function'
in ECMAScritp terms could be "an object that can be called"

Bringing this thread back from the dead...

Is there a way to reliably check whether I can call an object
as a function?
Not if you want to include methods of host objects in the set of objects that could be called.
You might reasonably say that if - typeof x - was 'function' then it would be safe to call the
object, and be correct in all the environments that I have ever encountered. But we both know
that would mean never calling host methods on Windows IE, which would be somewhat disappointing.

<snip>
I know the argument can be made that this is bad design
to not know whether or not you're passing in something
that can be called as a function.
Absolutely.
But I'm asking as a purely technical question, whether or
not it's possible.
Not possible in the general case. Possibly a case fro try-catch and handling the errors. Or
avoid the problem by designing the issue out of the system.

Richard.

Nov 26 '07 #25
VK
On Dec 1, 6:24 pm, VK <schools_r...@yahoo.comwrote:
1) Report the bug at bugzilla.mozilla.org
No need to do it:

https://bugzilla.mozilla.org/show_bug.cgi?id=296858
and
https://bugzilla.mozilla.org/show_bug.cgi?id=346789
as dups of
https://bugzilla.mozilla.org/show_bug.cgi?id=268945
"Applet tag returns function instead of object with typeof JavaScript
method".

Still a reference to bug ID would be helpful so side readers could
know if one looking for a particular bug workaround or with some
universal JS/DOM feature.
Dec 1 '07 #26
VK
On Dec 1, 9:03 pm, Matt Kruse <m...@mattkruse.comwrote:
else if ( ('ActiveXObject' in window) &&

This is and always has been a terrible way to infer anything.
Use conditional compilation instead, which will only run in the
JScript engine where the "problems" exist.
Unless someone will implement a browser with conditional compilation
and IE spoofing. :-))

Taking into account the OTC deal of browser producers ("spoof whatever
you need but ActiveXObject") this property check is very reliable as
well - again on condition that someone is trying to use your program
and not to get a runtime error. There is no protection for a
determined user of the latter kind - but he/she never was a subject of
my preoccupations. Within the same OTC deal for IE/Gecko branches it
is pretty secure to:
if ('ActiveXObject' in window) {
// IE branch
}
else if ('GeckoActiveXObject' in window) {
// Gecko block
}
else if ('opera' in window) {
// Opera block
}
else {
// some lesser-minor UA
}

Again: no offence of any kind to the conditional compilation instead.
((''+obj).indexOf('function')!=-1) ) {
return 'function';
}

This is way to broad. An object like
{ description:'This lets you test for a function'}
would be labeled a 'function' by your $typeof function.
Are you sure about it? ;-) Do not mix an object property value with
toString of the object itself.
Dec 1 '07 #27
VK
On Dec 1, 9:31 pm, VK <schools_r...@yahoo.comwrote:
((''+obj).indexOf('function')!=-1) ) {
return 'function';
}
This is way to broad. An object like
{ description:'This lets you test for a function'}
would be labeled a 'function' by your $typeof function.

Are you sure about it? ;-) Do not mix an object property value with
toString of the object itself.
What is bad in this block is that it will make unnecessary checks for
JScript objects where typeof always works just fine. Because in IE DOM
model DOM objects have nothing to do with JScript objects the
suggested optimization could be:

else if (('ActiveXObject' in window) &&
(!Object.prototype.isPrototypeOf(obj)) &&
((''+obj).indexOf('function')!=-1)) {
return 'function';
}
Dec 1 '07 #28
VK
On Dec 2, 12:14 pm, VK <schools_r...@yahoo.comwrote:
// # Because the problem affects only DOM elements
// # and because DOM elements are strictly separate
// # from JScript objects in IE then to secure ourselves
// # from overloaded toString and from unnecessary checks:

return Object.prototype.isPrototypeOf(o) ?
typeof o : /^function/.test(o);
}
}
Oops... The function always returns true/false, not typeof results:

return Object.prototype.isPrototypeOf(o) ?
(typeof o == 'function') : /^function/.test(o);
Dec 2 '07 #29
On Dec 2, 3:14 am, VK <schools_r...@yahoo.comwrote:
return Object.prototype.isPrototypeOf(o) ?
...
func += "if (RegExp.prototype.isPrototypeOf(o))"+
Fails across windows, yes?

Matt Kruse

Dec 3 '07 #30
On Dec 1, 7:24 am, VK <schools_r...@yahoo.comwrote:
On Dec 1, 5:28 pm, Matt Kruse <m...@mattkruse.comwrote:
I'm thinking the answer is to avoid having strong reliance on typeof
in checking arguments to functions, and then making further
assumptions based on the return of typeof. This is the typical fake
overloading approach -- switch on arguments[0], et c.

The reason the libraries get themselves in this situation is that
they're using this approach.

It's the fake overloading approach that is the problem. It is a
problem because it assumes things based on the return of typeof.

And so the best approach is to avoid using fake method overloading
with variant types/variant behavior per method. Instead, I think a
better approach is to use explicit methods.

That's my opinion,.

Dec 3 '07 #31
VK
On Dec 3, 7:21 am, Matt Kruse <m...@mattkruse.comwrote:
On Dec 2, 3:14 am, VK <schools_r...@yahoo.comwrote:
return Object.prototype.isPrototypeOf(o) ?
...
func += "if (RegExp.prototype.isPrototypeOf(o))"+

Fails across windows, yes?
Sorry for delay, I had to be out of town for a while..

One cannot use constructors from one window/frame for object
instantiations in the current window/frame: that leads to one of the
most obscure and random runtime errors in JScript: "Can't execute code
from a freed script". It may work for iframe, mostly fails for
frameset and window. Some maniacs still trying to hack it by using
call wrappers like
var foo = OtherWindowReference.FunctionName();
and in OtherWindow:
FunctionName() {
return new MyObject();
}

"freed script" error still comes sooner or later but even in more
random and obscure way. So yes, such misuse can be met in some
libraries, I saw it myself - but we decided(?) that we don't consider
neither developers devoted to make a non-working code, nor end-users
devoted to crash the program. From this point of view any arguments
about cross-Global OOP should be dismissed; as well as say a
possibility to use constructors and then patch __proto__ property
(where available).
Dec 7 '07 #32
VK
On Dec 3, 12:56 am, Matt Kruse <m...@mattkruse.comwrote:
On Dec 2, 3:14 am, VK <schools_r...@yahoo.comwrote:
// # conditional compilation needs a condition;

No it doesn't. It will run in the JScript engine,
and won't elsewhere. No need for a condition.
You are wrong: the minimum required syntax for pragma reader is:
/*@cc_on @ */
/*@if (some_condition)
// some source code
@else @*/
// some source code
/*@end @*/

The code you have originally posted simply leads to the "syntax error"
on IE. Without closing @end pragma it is still syntax error but more
informative: about missing end pragma. Sometimes it is not needed to
build any complex condition and the question only is "IE or not IE".
In such case one normally uses @if (@_jscript) check - it always
returns true for IE. So then really minimalistic conditional
compilation syntax is:

/*@cc_on @*/
/*@if (@_jscript)
// some source code
@else @*/
// some source code
/*@end @*/

One of defaults of the current implementation is that there is no
explicit way to write fall-through branching: so "include this if
(true) but also include the rest of source". As a workaround one
normally uses the above block with empty "else" branch:

/*@cc_on @*/
/*@if (@_jscript)
// some source code
@else @*/
// NOP
/*@end @*/
// the rest of code

Pre-processor has to be turned off as soon as not needed anymore.
Don't forget that it is not a parser on this stage - it is pre-
processor preparing text source code to be sent to parser. Don't make
him to keep going through the whole 10Kb - 600Kb js file in search of
more pragma commands. Inefficient first, dangerous second - in case of
same obfuscated source on the go.
// # if - else if - else, no pending 'if'
// # Not an error but if it's for public
// # attention then let's be accurate ;-)
else if (typeof o=='object') {

No need for else if the first block returns early from the function.
OK
// # On IE for DOM elements implicit toString call
// # returns either "function ..." or "[object]"
// # or "unknown" (for some external ActiveX controls):
// # so the 2nd check adds absolutely nothing to the job:
// # /\[native code\]/.test(o) removed
Actually, it is needed. In your version,
isFunction( ["function"] )
would return true.
On what browser? Again, you seem mixing property values of objects and
toString return value of object itself: they have nothing to do with
each other unless overloaded toString.
// * If you want to know about RegExp instances
// * then check for RegExp instances!

I suppose. I've never used isPrototypeOf, so I'd have to make sure
that it's a good choice to use it in this case.
You are not making a startup stage feature sniffing: you are making a
method for using runtime, possibly with hundreds and more calls at a
short period of time. In such case the proportion "more checks / more
speed" has to be shifted to "more speed" especially when the language
provides legal tools for it. IMHO.
// # Switch pragma reader off:
/*@end @*/})();

Not really necessary.
See the top of my post.
/*@end @*/
Dec 7 '07 #33

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: lawrence | last post by:
Suppose I create dynamic web pages with 3 functions (which call other functions to make everything happen, but these 3 you might think of as being the top layer): registerSessions();...
7
by: Alan Holloway | last post by:
Hi all, Firstly thanks for your golden insight on my earlier post re bitwise operations. I now have another question! I've just been reading the excellent Peter van der Linden excerpt ...
4
by: anonymous | last post by:
Thanks your reply. The article I read is from www.hakin9.org/en/attachments/stackoverflow_en.pdf. And you're right. I don't know it very clearly. And that's why I want to understand it; for it's...
4
by: Aaron Queenan | last post by:
When I build a C++ library to .NET using the managed C++ compiler, I get the following error message: Linking... LINK : error LNK2020: unresolved token (0A000005) _CrtDbgReport LINK : error...
9
by: tshad | last post by:
This is from my previous post, but a different issue. I have the following Javascript routine that opens a popup page, but doesn't seem to work if called from an asp.net button. It seems to work...
5
by: Sakharam Phapale | last post by:
Hi All, I am using an API function, which takes file path as an input. When file path contains special characters (@,#,$,%,&,^, etc), API function gives an error as "Unable to open input file"....
1
by: Michael D. Reed | last post by:
I am using the help class to display a simple help file. I generated the help file using Word and saving it as a single page Web page (.mht extension). I show the help file with the following...
1
by: DJG79 | last post by:
Hi all, I am using an open source menu that i found and it works great, except for one thing that when the web page is not scrolled to the very top the drop down links will not stay visible. Has...
6
by: Murray Hopkins | last post by:
Hi. THE QUESTION: How do I get a reference to my Object when processing an event handler bound to an html element ? CONTEXT: Sorry if it is a bit long. I am developing a JS calendar tool....
1
anfetienne
by: anfetienne | last post by:
i have this code below that i made....it loads vars from txt file splits it then puts it into an array....once in an array it the brings the pics in from the array to create thumbnails and a larger...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.