When is a function not a function?

R

Richard Cornford

There you go again.

And there you go again. Instead of being interested in why I think 50%
of what you wrote is somewhere between uninformed and nonsense you would
rather disregard the comment and leave it as it is.

The subject is expected NOT to be any of those things.

If the subject (the value that is subject to the tests) were not
expected to be a string what would be the point of seeing how the
results of - typeof - compared with 'string'? If it could not be a
string then the outcome would be known at the point of writing the code
and no runtime test would be required. The same goes for every other
test.
The point of each test is to exclude these things.

If the subject of the test is not expected to potentially be the things
that are excluded there is no point making any effort to exclude them.
Just maybe, there's
some type of node that says it's a "function" to typeof.

There is nothing to say that an object implementing the Node interface
should not be a function object.
It's actually likely in Safari; Safari thinks document.images
is a function, which it is Not!

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" (i.e. subject to the 'call
operator' without that act of itself directly resulting in an exception
being thrown (later exceptions, such as winging about the types or
number of arguments are not related to the callability of the object)).
Under that definition Safari's - document.images - is a function, as it
can be called.
Now I should clear up a bit of confusion you posted on the
webkit bug:

Take an object that is an instance of an NodeList.

NodeList is an interface not a 'class'. Which is a good thing, as
ECMAscript/javascript has no notion of 'classes'. But even in
class-based languages like Java an object implementing an interface is
not necessarily an object of any particular (or any single) class.

Javascript is a very flexible language and it loves interfaces. You can
take an object, any object, and retro-fit an interface to it at runtime.
And you can add the interface to any number of objects with very diverse
origins to the extent that they have nothing else in common that could
be regarded as asserting their 'type'.

The result is that any notion of "an instance of an NodeList" has very
little meaning in javascript. It may or may not reflect an internal
implementation detail, but beyond that it is no more than a perception
in the mind of a programmer.
That object's constructor implements NodeList.

Absolutely nothing, anywhere, makes any assertions about constructors in
relation to object that implement the NodeList interface.
The object itself is an object.

An object implementing the NodeList interface must be an object, but is
not required to be anything more. And it can be expected to be a host
object, so almost nothing else can be asserted about it with authority.
The fact that it is callable is a bug,

No. Object can be callable. At least the things that are callable in
javascript are all objects.
copied from MSIE, who made document.all, etc. a function,
e.g. document.all(0). Mozilla copied this.

And copied by nearly every other browser since, with a significant
proportion of them also returning 'function' from - typeof - operations
on those objects.
It is retarded, IMO.

It is certainly unnecessary and unhelpful, but it is (and has for some
considerable time been) a reality.
javascript:alert(Function.prototype.call.call(
document.links,document, 1))

Not really useful. OR good design.

An instance of a NodeList is NOT the object that
implements NodeList.

An object that implements the NodeList interface is precisely what the
W3C DOM specifications define it as. Making any assertion beyond that
would be technically groundless.
The object that implement's NodeList is the instance's
constructor.

Can you find any authorities statement supporting that assertion?
Neither of the applicable documents (Core DOM and its ECMAScript
bindings and ECMA 262) are that big so it should not take too long to
look.
What objects are those?

Objects that inherit from functions.
Only ones that incorrectly report "function"
for typeof, I hope.

Have you identifier any objects that do "incorrectly" report 'function'?
We have seen that the objects that are concerning you are callable
(which would be a fine justification for reporting 'function') and that
they are host objects (so they may report anything at all). Where does
your definition of "incorrectly" come from?
What I prefer about the dojo function

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);
| }
| }
is at least it is less inclusive.
It filters out with the typeof operator.

document.links instanceof Function; // false in Safari.

But it will include any non-function object that has a function on its
prototype chain, so the objects that are 'isFunction' are not
necessarily even executable. It makes you wonder what it is they think
they are testing for.

That's what I'm saying. If jQuery's isFunction gets a falsish value,
a string value, et c, that value is excluded. It's "none of", not
"any of". You're wrong.

No I am right. If the subject of the test (the value that is tested)
were not expected to be any of those possibilities then there would be
no point in testing them with the intention of excluding them.
http://www.m-w.com/dictionary/betray

I'm pretty sure you meant "betrays good design," as that's the
gist of what you're saying.

It is in the nature of bad design that it attempts to hide. Here the bad
design has been exposed by the test code. The bad design has been
betrayed by the code and so its attempt to hide from observation has
been unsuccessful. Thus the test code betrays the bad design.

When I use others' code, I want it to fail right away if I use it
wrong. Now it might have been my fault for passing in an undefined,
but hey, I'm human and I lose my keys, I've put shit in the washer
that shouldn't go there, (phone, et c).

When others use my code it should fail fast and report the error
properly.

Now if some library had a function that takes a callback, that would
be when you want to know "is the callback a function?"

It would be better to have some more precise definition of what you
meant by 'a function' here. Do you just mean something that can be
called, or do you really want to discriminate between programmer defined
functions and everything else? Pinning down precisely what you need to
know is a necessary pre-requisite of designing an effective test that
will tell you that.
function doStuff( errorHandler ) {

}

When will errorHandler be invoked? Maybe never, right?

That would depend on your testing. Including an error handler and then
not testing whether it handled the errors correctly would seem reckless
to me.
Or maybe it will be invoked some time after deployment, maybe
even after I'm gone from the job. Wow, that would suck.

So you would write code for a job and then walk away without testing
that it worked as designed?
Wouldn't it make sense to check the errorHandler 'thing' and
make sure it's actually a function first?


function doStuff( errorHandler ) {
if(typeof errorHandler != "function") "
var err = new Error("hey stoopid...");
log(err);
throw err;
...
}

Not as much sense as deliberately provoking the error in testing and so
knowing that it did work.
<snip>

Richard.
 
R

Richard Cornford

David said:
On Oct 13, 10:28 pm, Richard Cornford wrote:
[snip]
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?

The objects that Safari claims are functions are indeed callable.
They have the internal [[Call]] method, but do not implement
Function.prototype.call.

Which is also true of built in functions such as - parseInt - (by
specification).

test function
test object
test function
test object
undefined
undefined
undefined

Safari returns:

test function
test object
test function
test object
[Object HTMLImageElement]
[Object HTMLImageElement]
undefined

So the validation is enough to prevent errors, but not
enough to maintain consistent results for the test cases.

But the results are still correct for all of those browsers. The -
document.images - object can be called in Safari and calling it has a
predictable outcome.
The pattern is clear though.

function isFunction(f) {
return (typeof f == 'function' && typeof f.call == 'function');
}

Now you are starting to narrow down on what you mean by 'a function'.
You have excluded the built in functions and are being left with just
programmer defined functions and methods. If that is the discrimination
you want to make then you have a test for that. The problems with all
the previous examples of - isFunction - is that there authors have not
worked out what the discrimination they are trying to make is, and so
are creating functions with pretty much arbitrary outcomes.

The revised versions bring Windows Safari (and the like) into line.

It is worth pointing out (again) that historically it is absolutely
normal for objects implementing NodeList, HTMLCollection and pretty much
any other collection interface to be both callable and to return
'function' form a - typeof - test. This was true for Mac IE, Opera
versions at least up to 7.nn, Konqueror, IceBrowsr up to 5 and probably
many others. Safari is not doing anything unusual or unexpected here so
Safari's behaviour is against the expectations of anyone then it is
those expectations that are at fault.

Richard.
 
T

Thomas 'PointedEars' Lahn

Randy said:
Richard Cornford said the following on 10/14/2007 11:18 AM:

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.
Then Safari is right and IE/FF/Opera are wrong?

It is not a matter of right and wrong.


PointedEars
 
R

Richard Cornford

Randy said:
Richard Cornford said the following on 10/14/2007 11:18 AM:

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.

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

Thomas 'PointedEars' Lahn

Randy said:
Thomas 'PointedEars' Lahn said the following on 10/14/2007 2:00 PM:
Randy said:
[Safari 3 Beta for Windows yields typeof document.images == "function"]
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?

There is, but see below.
That part is confusing to me. I thought any and everything was an Object,

It's not, but I hope that this value-object duality will be resolved
eventually in favor of "everything is an object" with ES 4. (As much
as I hope the wave-particle duality in quantum mechanics will be
resolved some time soon, only that the former is more probable :))
at least underneath,

If you mean by that when a method is used on a primitive value this value
can be type-converted into a corresponding object, then you are correct:

"bla".charAt(0)
(12.41).toFixed(1)
and that functions were merely augmented Objects.

Functions/methods are special objects that can be called and inherit from
Object.prototype.
That implies to me that anything and everything should return object or
some subset of object.

The `typeof' operator is well-defined in ES 3 Final, 11.4.3, which includes
the provision for implementations that they yield *any* value on that
operation for host objects:

| 5. Return a string determined by Type(Result(4)) according to the
| following table:
|
| Type Result
| ---------------------------------
| Undefined "undefined"
| Null "object"
| Boolean "boolean"
| Number "number"
| String "string"
|
| Object (native and "object"
| doesn’t implement
| [[Call]])
|
| Object (native and "function"
| implements [[Call]])
|
| Object (host) Implementation-dependent
^^^^^^^^^^^^^^^^^^^^^^^^

Fortunately for us developers, implementors so far have chosen to have
their implementations yield only "function" or "object" then (CMIIW).


PointedEars
 
T

Thomas 'PointedEars' Lahn

Thomas said:
Functions/methods are special objects that can be called and inherit from
Object.prototype.

D'oh. Make that Function.prototype.
 
D

David Mark

On Oct 14, 11:18 am, "Richard Cornford" <[email protected]>
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.
 
P

Peter Michaux

Hi David,

var global = this;
var setOpacity = (function() {
var i, l, html;
var doc = global.document;
var opacityStyles = ['opacity', 'MozOpacity', 'KhtmlOpacity'];


Did you test the "KhtmlOpacity" property on early version of Safari
yourself? I have not and have also seen it written as "KHTMLOpacity"
and "KHtmlOpacity".

Peter
 
M

Matt Kruse

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?

For example, in IE6:
var input = document.createElement("input");
input.type = "text";
document.body.appendChild( input );
var prop = "focus";
alert(typeof input[prop]); // object
alert(typeof input[prop].call); // undefined
input[prop](); // works

What test could I do to ensure that the last line will never cause an
error, no matter what the value of "prop" is, and still work correctly
for things like "focus"? Is it possible?

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. But I'm asking as a purely technical question, whether or
not it's possible.

Matt Kruse
 
R

Richard Cornford

Matt said:
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.

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

VK

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?

For example, in IE6:
var input = document.createElement("input");
input.type = "text";
document.body.appendChild( input );
var prop = "focus";
alert(typeof input[prop]); // object
alert(typeof input[prop].call); // undefined
input[prop](); // works

What test could I do to ensure that the last line will never cause an
error, no matter what the value of "prop" is, and still work correctly
for things like "focus"? Is it possible?

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. But I'm asking as a purely technical question, whether or
not it's possible.

In "standard" clj terms ("it is not possible for 100% - it is not
possible at all") it is not possible.

The evident way is to use typeof:
if (typeof something == 'function') {
}

but in IE some/many native methods of window or document are reported
as "object" instead of "function" despite still can be used in [Call]
context.

try {
something();
}
catch(e) {
}

is another way but "there can be UAs that don't support blah-blah"

So the answer is: it is possible for any current practical extend but
it is not possible as an absolutely bulletproof solution.
To call it "possible" or "not possible" is up to you.
 
M

Matt Kruse

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.

Unfortunately, in Firefox:

var o = document.createElement("object");
alert(typeof o); // "function"
o(); // ERROR

Btw, earlier in this thread there was a complaint about jQuery's lack
of explanation for its code and lack of test cases, so I thought I
would point this out:
http://dev.jquery.com/browser/trunk/jquery/test/unit/core.js#L62

This is actually the origin of the above case that fails in FF.

Matt Kruse
 
V

VK

Unfortunately, in Firefox:

var o = document.createElement("object");
alert(typeof o); // "function"
o(); // ERROR

For such primitive case one may use isPrototypeOf method:

var x = document.createElement('object');
var y = new Function;
window.alert(Function.prototype.isPrototypeOf(x)); // false
window.alert(Function.prototype.isPrototypeOf(y)); // true

Again the prototype chain might be screwed up completely, on Gecko
including the direct hack of __proto property, so se my other post
about what one may consider as "possible" or "not possible".
 
T

Thomas 'PointedEars' Lahn

VK said:
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. But I'm asking as a purely technical question, whether or
not it's possible.

In "standard" clj terms ("it is not possible for 100% - it is not
possible at all") it is not possible.

The evident way is to use typeof:
if (typeof something == 'function') {
}

but in IE some/many native methods of window or document are reported
as "object" instead of "function" despite still can be used in [Call]
context.

The most obvious and oft-recommended solution is

/**
* @author
* (C) 2003, 2004 Thomas Lahn &lt;[email protected]&gt;
* Distributed under the GNU GPL v2.
* @partof
* http://pointedears.de/scripts/types.js
* @optional string s
* String to be determined a method type, i.e. "object"
* in IE, "function" otherwise. The type must have been
* retrieved with the `typeof' operator, thus this method
* is applicable to unknown properties while
* @link{#isMethod()} is not. Note that this method
* may also return <code>true</code> if the value of
* the <code>typeof</code> operand is <code>null</code>; to
* be sure that the operand is a method reference, you have
* to && (AND)-combine the <code>isMethodType(...)</code>
* expression with the method reference identifier.
* @return type boolean
* <code>true</code> if <code>s</code> is a method type,
* <code>false</code> otherwise.
* @see #isMethod()
*/
function isMethodType(s)
{
return /\b(function|object)\b/i.test(s);
}

and then

if (isMethodType(typeof o.property)
&& o.property)
{
... o.property(...) ...
}

which has sufficed to date.


PointedEars
 
M

Matt Kruse

The most obvious and oft-recommended solution is:
function isMethodType(s)
{
return /\b(function|object)\b/i.test(s);
}
and then
if (isMethodType(typeof o.property)
&& o.property)
{
... o.property(...) ...
}
which has sufficed to date.

in IE:

function isMethodType(s) {
return /\b(function|object)\b/i.test(s);
}
function isFunction(o) {
return !!o && isMethodType(typeof o);
}
window.onload = function() {
alert(isFunction(document.body.firstChild)); // true
//document.body.firstChild() // ERROR
var a = document.createElement("a");
document.body.appendChild( a );
alert(isFunction(a)); // true
//a(); // ERROR
}

Matt Kruse
 
R

Richard Cornford

Matt said:
Unfortunately, in Firefox:

var o = document.createElement("object");
alert(typeof o); // "function"
o(); // ERROR

You are making a surprisingly obvious mistake here. You are assuming that because calling a
function results in an exception being thrown then that means that the function/object is not
callable. When you think about that it is pretty obvious that such a conclusion is not valid.

In Firefox, when you call an object that is not callable the exception thrown is "o is not a
function", but the exception here is "Component is not available", so you cannot prove that the
object is not callable, only that calling it throws an exception. It could be that if and when
the "Component" (whatever that may be in this case) was available you could happily call the
function/object without an exception being thrown.

The bottom line is that an object's being callable is no guarantee that calling will be an error
free operation.

This is actually the origin of the above case that
fails in FF.

So this is not your mistake, you just didn't think about it enough to see who was being fooled
here.

Richard.
 
M

Matt Kruse

In Firefox, when you call an object that is not callable the exception thrown is "o is not a
function", but the exception here is "Component is not available", so you cannot prove that the
object is not callable, only that calling it throws an exception.

This gets into a pretty gray area, then, doesn't it? How could you
ever know that _any_ object that is callable will not result in an
error? Should everything be wrapped in a try/catch?

Your original statement was:
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.

so I was trying to demonstrate a situation where it is not in fact
"safe" to call an object with typeof=="function". If by "safe" you
mean "won't throw an error".
The bottom line is that an object's being callable is no guarantee that calling will be an error
free operation.

But if you extend that to the absurd, then you have no guarantee that
calling something like alert() will be an error free operation, do
you?

I think it should be safe to conclude that anything reporting itself
as typeof=="function" should be callable without throwing an error,
and in this case FF has a bug. Nevertheless, it's a bug that needs to
be worked around in any code that is trying to figure out if a given
object should be treated as a callable function.

The root cause of this mess in jQuery seems to be that the API tries
to "overload" methods to handle various types of arguments, like

func(object, object)
or
func(object, function)

so there is a "need" to figure out which type of method signature is
being called. I do tend to like this kind of "overloading" in many
cases because it results in very dense and flexible code, but given
the problems involved in truly testing whether an argument is a
callable function, I think this design decision is a flaw.

Matt Kruse
 
R

Richard Cornford

Matt said:
This gets into a pretty gray area, then, doesn't it?

It suggests that there is limited use in knowing that something is callable.
How could you ever know that _any_ object that is
callable will not result in an error?

By knowing what it is you are calling (say knowing that - document.getElementById - is forbidden
from throwing an exception) or by testing that conditions that would result in an exception
being thrown don't apply before taking actions that may result in their being thrown.
Should everything be wrapped in a try/catch?

Almost nothing should be wrapped in try-catch because javascript's exception handling is far too
poor to allow sensible error handling. Defensive programming to avoid runtime errors is a far
superior approach.
Your original statement was:

so I was trying to demonstrate a situation where it is
not in fact "safe" to call an object with
typeof=="function".

And you did not do that.
If by "safe" you
mean "won't throw an error".

The act of calling the object has not been shown to throw an error. Instead the consequence of
calling; the resulting execution of code, appears to be where the exception is occurring.
But if you extend that to the absurd, then you have no
guarantee that calling something like alert() will be
an error free operation, do you?

Fortunately browsers are rarely absurd. Remember that you started off trying to call the object
returned from - document.createElement("object") - without any reason for expecting that to have
any certain outcome at all.
I think it should be safe to conclude that anything
reporting itself as typeof=="function" should be
callable without throwing an error,

Don't be ridiculous. Even programmer defined functions are allowed to throw exceptions while
they execute.

Remember that host methods may throw exceptions if they receive the wrong number or type of
arguments (that is pretty common) and knowing that something is callable will not tell you
anything about the arguments that it is expecting when it is called.
and in this case FF has a bug.

What makes it a bug?
Nevertheless, it's a bug that needs to be worked
around in any code that is trying to figure out if a given
object should be treated as a callable function.

Given that knowing something is callable is never enough to tell you that calling it will be
error free you are just describing a stupid design and then saying that the aspects of the
design that make it stupid become a problem in context.

Don't design code that attempts to call function/methods without first having a very good idea
of what those functions/method are, and what the consequences of calling them is likely to be.
The root cause of this mess in jQuery seems to be that
the API tries to "overload" methods to handle various
types of arguments, like

func(object, object)
or
func(object, function)

so there is a "need" to figure out which type of
method signature is being called.

Maybe, but we have already discovered that JQuery written by a novice who is far too arrogant to
even consider whether he has made any mistakes, let alone recognise the ones he has made. How
often have we witnessed that superficial success in the early stages of learning javascript
result in individuals acquiring a total unrealistic overconfidence in their own abilities?
I do tend to like this kind of "overloading" in many
cases because it results in very dense and flexible code,
but given the problems involved in truly testing whether
an argument is a callable function,

But clearly the issue is not whether the argument is callable or not. We have seen that that
information alone is not sufficient here. You certainly learn nothing about the number and type
of any possibly required arguments from that information, and that is just the start of the
ongoing problems with such a reckless strategy.
I think this design decision is a flaw.

Absolutely, but what chance of it being fixed in this library? The fix would radically alter the
nature of the API, and so render all pre-existing code that uses the library non-updateable. It
is a pity that the people who make these things do not spend some time learning the browser
scripting issues before they start because then they may be able to avoid tying hundreds of
other people's projects to their ill thought out code.

Richard.
 
T

Thomas 'PointedEars' Lahn

Matt said:
in IE:

function isMethodType(s) {
return /\b(function|object)\b/i.test(s);
}
function isFunction(o) {
return !!o && isMethodType(typeof o);
}
window.onload = function() {
alert(isFunction(document.body.firstChild)); // true
//document.body.firstChild() // ERROR
var a = document.createElement("a");
document.body.appendChild( a );
alert(isFunction(a)); // true
//a(); // ERROR
}

Firstly, one problem problem with your implementation is that it evaluates
the value before determining its type, where mine does it vice-versa.

Secondly, you are missing the simple fact that noone in their right mind
would try to determine if a document node would be callable.


PointedEars
 
M

Matt Kruse

Secondly, you are missing the simple fact that noone in their right mind
would try to determine if a document node would be callable.

I must have missed the note in your documentation that says what you
can and can't pass to get accurate results. So you have to know what
something is ahead of time, before determining if it is callable?

Imagine a function that can take any type of input, and does different
things depending on what is passed in. You might need to determine if
the user has passed in a callable object or a document node.

It's already been said that there is probably no fool-proof way to
determine if something is truly callable. Your "solution" which has
limitations and gets it wrong in some cases is really no improvement
over countless other attempts.

Matt Kruse
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top