How can a constructor be made so that calling it with "new" is optional?

R

RobG

(regarding this format:)
| jQuery.Event = function (src) {
|   if (!(this instanceof jQuery.Event)) {
|     return new jQuery.Event(src);
|   }
|   // continue as called with new...
| }


I'm not sure if that emoticon is to suggest that no one here would
bother.

That's the one.
 I would.  I did.  I brought it up on jQuery's developer's
forum here:

   http://forum.jquery.com/topic/why-does-jquery-event-use-preventdefaul...

Full marks for persisting with that crappy interface. It seems to be
all the rage now - no threading and actively discourage quoting. It
does look nice though, if you don't care about functionality.
and got into a debate with one person who thought this suggestion was
an attempt to prove I'm smart by breaking the code  :) and worried
about the 11 additional source-code characters.  Another member (one
of the core developers) was more interested.  He responded: "I'm not
inclined to change this code since nobody has ever reported a problem
with it.", which IMHO is not unreasonable although perhaps a little
short-sighted.  He also did some research to find out WHY this is
being done this way, but received no real satisfaction.  I wouldn't be
at all surprised to find that after kangax published his article,
someone swept through the JQ code and blindly eliminated all
`instanceof` operators, even if they did not have the relevant cross-
frame issues.

For me it's a matter of making the code robust. Why have a less than
optimal test when a more or less bullet-proof one is available at zero
cost? Even if it never breaks or is never shown to break "in real
life"?

The comment "if you write unexpected code, unexpected things will
happen" is priceless for a library that has a lot of code second
guessing what the programmer really wanted from its overloaded
methods.

If I had a bit more free time, I'd create a demo plug-in to show the
sorts of things that look reasonable but might break JQ without this
fix, then submit a patch.  But I'm pretty swamped right now.

Sure you're not just itching to show off? ;-p
 
A

Andrea Giammarchi

Stefan Weiss wrote:
`jQuery.fn` is just an alias to jQuery.prototype.  `init` is the
actual constructor function used.  Again, I'm guessing there might be
some faulty memory here since, in these days at least, the relevant
code looks like this:

(inside an immediately invoked function expression)
|    var jQuery = function( selector, context ) {
|      return new jQuery.fn.init( selector, context, rootjQuery );
|    },

and the actual `init` function, which is the true constructor, does
not use any similar type checking.


precisely the third example I have showed already :)

var MyConstructor = (function(){
function _MyConstructor(a, b, c) {
return new MyConstructor(a, b, c);
}
function MyConstructor(a, b, c) {
// initialization here ...
}
// define MyConstructor.prototype
_MyConstructor.prototype = MyConstructor.prototype;
return _MyConstructor;
}());

Above code was indeed simulating the jQuery behavior where

jQuery.prototype.init.prototype = jQuery.prototype

r vice versa, it does not matter

the fn is indeed a shortcut for the prototype so Rob, about that:

That seems to be redundant, since no matter how _MyConstructor is
called, it will always call:
new MyConstructor(...)

Yes, jQuery constructor does redundant operation but this is meant
since nobody would like to write
new $(...)
instead of
$(...)

The prototype chain is to make
$(...) instanceof $; // true

Have a nice day,
Andrea Giammarchi
 
S

Scott Sauyet

RobG said:
Full marks for persisting with that crappy interface. It seems to be
all the rage now - no threading and actively discourage quoting. It
does look nice though, if you don't care about functionality.

It's easy enough to use to START a discussion. And I could probably
live without threading if the view was entirely flat. But instead
they offer a 2-ply system: you can add a message to the main thread,
or you can offer a comment on a top-level message. But that's it.
You can't reply to the comments. It really is the worst of both the
flat and the threaded models!

But it's so pretty! :)
For me it's a matter of making the code robust. Why have a less than
optimal test when a more or less bullet-proof one is available at zero
cost? Even if it never breaks or is never shown to break "in real
life"?

Although I agree, and that's what I meant by saying that the response
is a little short-sighted, I do understand the reluctance to introduce
a change that might somewhere, somehow break code that's taking
advantage of the current behavior -- especially when there have been
no reports of the current implementation having issues. But blind
insistence on backward-compatibility is also what leads to Microsoft-
style bloat. jQuery could use a huge refactoring. But I can't see
them being willing, now that it's so popular, to take the risk. The
last time I remember a large breaking change to their public API was
when they dropped XPath support in their selectors. That was hard
enough, and they were not nearly so popular then.
The comment "if you write unexpected code, unexpected things will
happen" is priceless for a library that has a lot of code second
guessing what the programmer really wanted from its overloaded
methods.

I think he was just a fan-boy. I haven't seen such attitude from the
core team.

I'm really mixed about their overloading. The get/set style
overloading doesn't bother me at all. But the number of things the
jQuery constructor (and it's `$` alias) does is crazy.

Sure you're not just itching to show off? ;-p

Maybe, but I don't think it would be enough of a challenge to satisfy
that itch. ;-p

-- Scott
 
R

Richard Cornford

The overall outcome is a little disappointing. I'm not familiar
enough with jQuery to judge the actual impact of this problem...
maybe someone can enlighten me. Did I understand correctly that
jQuery plugins can - and do - add random properties to the main
jQuery object, basically without naming restrictions except to
avoid conflicts with the official jQuery API? In this case, there
could well be a problem with a (future) plugin adding a
"preventDefault" property, and it would be better to be safe than
sorry.

Didn't the subject of interest start out as - JQuery.Event -? So
adding preventDefault methods to the JQuery object itself should not
impact there (though I really should go an look at the source code
before assuming that JQuery.Event is no more convoluted than it needs
to be).
For reference, the original code author's comments were

| I'm not 100% sure now, it's been a while. I guess the reasons were:
|
| - cross frame compat
| - Seems simpler (short and clean)
| - There was no instanceof [in some browsers] at that time I think
| - I'm pretty sure I took jQuery.fn.init as a reference which at that
| time did stuff like that.

"cross frame compat" is of no concern in this case.

Why not? My impression has been that if JQuery is to be used in a mult-
frame environment it needs to be included in each frame, so any cross-
frame communication would imply its having to identify JQuery object
that were not necessarily created with constructors from the current
frame.
"seems simpler" - okay, maybe - "(short and clean)" - it's no
longer clean if it can be a source of unintentional behavior, IMO.

This seems to be part of the reason for this entire thread; solving
the wrong problem. Any situation where you are using - new - in some
places and not using it in others, but in all you are trying to do the
same thing (construct new (specific) objects) is going to detract from
the comprehensibility of that code. It should be one thing or the
other, not either/both. And personally I think that if what you are
conceptually doing is creating new objects (rather than creating new
objects incidentally, which is the JQuery style) then the use of the -
new - keyword in front of a capitalised constructor function name
makes that intention explicit.
"there was no instanceof" - really? I'm not sure, but that seems
rather unlikely. Doesn't jQuery have a list of supported browsers?
I would be very surprised if there was any browser on that list
three years ago (which is when that piece of code was added, I
think) that didn't support instanceof. Thomas Lahn might know more
about that.

The - instanceof - operator was introduced into the standard in ECMS
262 3rd Ed., so December 1999. IE 5, Opera 6 and Netscape 6 all had
it, so it was well established long before JQuery was written.
"jQuery.fn.init" - (sorry, can't comment on that, I have no idea what
this function does)

As an aside, I'm glad we can finally discuss techniques used in
libraries like jQuery, without somebody going off about how jQuery
is *evil*. I may not use jQuery, but I'm still interested in why
they do things the way they do.
<snip>

I am often interested in why JQuery has been doing some of the things
it has done historically. It is a pity that the comments form the
source code tend to not explain anything.

Richard.
 
S

Scott Sauyet

Richard said:
Didn't the subject of interest start out as - JQuery.Event -? So
adding preventDefault methods to the JQuery object itself should not
impact there (though I really should go an look at the source code
before assuming that JQuery.Event is no more convoluted than it needs
to be).

Well, the subject was really about how jQuery.Event was written so
that these two lines had equivalent results:

var evt = new jQuery.Event("click");
var evt = jQuery.Event("click");

That is, how can the `new` operator be made optional?

jQuery.Event is not particularly convoluted:

| jQuery.Event = function( src ) {
| if ( !this.preventDefault ) {
| return new jQuery.Event( src );
| }
|
| this.type = // calcluated from src parameter
| this.timestamp = // ...
| // ...
| };

But they definitely want to use it with and without the `new`
operator. The problem is that if something added "preventDefault" to
the jQuery object itself, then `this.type = ...` would be called with
the jQuery object. Unfortunately, that would overwrite another
function already used internally.

For reference, the original code author's comments were
| I'm not 100% sure now, it's been a while. I guess the reasons were:
|
| - cross frame compat
| - Seems simpler (short and clean)
| - There was no instanceof [in some browsers] at that time I think
| - I'm pretty sure I took jQuery.fn.init as a reference which at that
|   time did stuff like that.
"cross frame compat" is of no concern in this case.

Why not? My impression has been that if JQuery is to be used in a mult-
frame environment it needs to be included in each frame, so any cross-
frame communication would imply its having to identify JQuery object
that were not necessarily created with constructors from the current
frame.

The alternative under discussion is

| jQuery.Event = function( src ) {
| if ( !(this instanceof jQuery.Event) ) {
| return new jQuery.Event( src );
| }
|
| this.type = // calcluated from src parameter
| this.timestamp = // ...
| // ...
| };

I can't see any case where `instanceof` used like this would run into
that cross-frame compatibility issue. Am I missing one?

This seems to be part of the reason for this entire thread; solving
the wrong problem. Any situation where you are using - new - in some
places and not using it in others, but in all you are trying to do the
same thing (construct new (specific) objects) is going to detract from
the comprehensibility of that code. It should be one thing or the
other, not either/both. And personally I think that if what you are
conceptually doing is creating new objects (rather than creating new
objects incidentally, which is the JQuery style) then the use of the -
new - keyword in front of a capitalised constructor function name
makes that intention explicit.

I agree that within one's own code, this is a good idea. But in
library code, I have mixed feelings. If you can add such filters to
keep the library from failing entirely on some bad input, it's often a
good idea. A less friendly, but still useful version would be this:

| jQuery.Event = function( src ) {
| if ( !(this instanceof jQuery.Event) ) {
| throw new Error("jQuery.Event must be called with `new`");;
| }
| // ...
| };


Honestly, I wouldn't be surprised if one of the main reasons for this
is to save the four characters of `new ` in multiple places in the
code, which does not seem to me to be nearly enough of a reason.

-- Scott
 
V

VK


Because such programming paradigm is explicitly forbidden and on IE/
JScript leads to "Can't execute code from a freed script" run-time
error: yet there are known ways to cheat on this protection. So the
message of the author of the linked article
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
is as read it: "I managed to write a specially crafted code that
allowed me to bypass built-in run-time engine analyzer. By using this
code I managed to force instanceof operator to get dizzy in some
circumstances. Conclusion: instanceof operator considered harmful in
Javascript programming".
I beg everyone's pardon but it is a sample of the frick logic. This
way one can prove the harmfulness of anything including +, - and *

Another fricky stuff that bothers me is that recent paranoid desire to
skip on "new" and to force function calls act as constructor calls
despite the fact that these are completely different programming
entities with different meaning and behavior.
I am thinking to make a social test by posting at C++ professional
forums something like "I am migrating from Javascript to C++ and I am
wondering how to make "MyClass()" call to be equivalent to "new
MyClass()" call. I used to this overloading and find it very evident
and convenient: yet I am still struggling to find a way to do the same
in C++".
It is not interesting if it's indeed possible in C++ (I would presume
that not). It would be interesting to read comments on such post about
my programming knowledge, culture and the state of my mental health...

Though I assume I know from where the stinky wind is blowing. From the
same place maybe where "new operator is considered harmful" and
var obj = {}; // is professional and OK
while
var obj = new Object(); // is unprofessional and harmful

I assume others may also know the location and the name of the
person...
 
J

J.R.

Because such programming paradigm is explicitly forbidden and on IE/
JScript leads to "Can't execute code from a freed script" run-time
error: yet there are known ways to cheat on this protection. So the
message of the author of the linked article
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
is as read it: "I managed to write a specially crafted code that
allowed me to bypass built-in run-time engine analyzer. By using this
code I managed to force instanceof operator to get dizzy in some
circumstances. Conclusion: instanceof operator considered harmful in
Javascript programming".
I beg everyone's pardon but it is a sample of the frick logic. This
way one can prove the harmfulness of anything including +, - and *

Another fricky stuff that bothers me is that recent paranoid desire to
skip on "new" and to force function calls act as constructor calls
despite the fact that these are completely different programming
entities with different meaning and behavior.
I am thinking to make a social test by posting at C++ professional
forums something like "I am migrating from Javascript to C++ and I am
wondering how to make "MyClass()" call to be equivalent to "new
MyClass()" call. I used to this overloading and find it very evident
and convenient: yet I am still struggling to find a way to do the same
in C++".
It is not interesting if it's indeed possible in C++ (I would presume
that not).

It does make sense, although 'skip on "new" and to force function calls
act as constructor' is just one of the known JS patterns. No one is
obliged to follow that pattern.
It would be interesting to read comments on such post about
my programming knowledge, culture and the state of my mental health...

Though I assume I know from where the stinky wind is blowing. From the
same place maybe where "new operator is considered harmful" and
var obj = {}; // is professional and OK
while
var obj = new Object(); // is unprofessional and harmful

Wait. In this specific case, you are not 100% correct. According to
Stoyan Stefanov, one of the JS Mentors, "the Object() constructor
accepts a parameter and, depending on the value passed, it may decide to
delegate the object creation to another built-in constructor and return
a different object than you expect". Examples copied from JS Patterns
book (by Stoyan Stefanov):

// an empty object
var o = new Object();
console.log(o.constructor === Object); // true

// a number object
var o = new Object(1);
console.log(o.constructor === Number); // true
console.log(o.toFixed(2)); // "1.00"

// a string object
var o = new Object("I am a string");
console.log(o.constructor === String); // true
// normal objects don't have a substring()
// method but string objects do
console.log(typeof o.substring); // "function"

// a boolean object
var o = new Object(true);
console.log(o.constructor === Boolean); // true

In his excellent book, Stoyan also illustrate other reasons to avoid the
new Object(), String(), Number(), Array(), etc. antipattern altogether.

I assume others may also know the location and the name of the
person...

Douglas Crockford, Stoyan Stefanov, and many others at Yahoo!, Mozilla,
Google, etc. etc.

Cheers,
Joao Rodrigues (J.R.)
 
V

VK

Wow... Did someone in Google got really upset or it was just a Usenet
problem? I saw J.R. response for about 5 minutes and then on page
update it just disappeared both from the thread and from J.R. posting
history.

I am answering to what I remembered:

I don't know a Javascript guru Stoyan Stefanov but I am ready to
believe that he is a knowledgeable specialist. For the Object
constructor matter:

var obj = {}; // Object initialiser

var obj = new Object(); // Object constructor call

var obj = new Object; // Object constructor call w/o parenthesis

are absolutely the same and being processed by the same algorithm in
Javascript. So if someone is really up to for saving keystrokes they
better do it from the right side. :)

The "spooky booh" with new Object(1), new Object("foobar") is
propaganda to disregard. Whatever happens with Object called with
different arguments is written in details in language references. If
it leads to a surprise of a programmer then where is the Javascript
fault? Most importantly OOP is not about creating Object instances. It
is about creating MyObject, MyExtendedObject from MyObject,
MyXtendedObject from MyExtendedObject etc. Unless of course I am
completely off from modern OOP interpretations.
 
J

J.R.

Wow... Did someone in Google got really upset or it was just a Usenet
problem? I saw J.R. response for about 5 minutes and then on page
update it just disappeared both from the thread and from J.R. posting
history.

I’ve unwittingly posted via
<https://groups.google.com/forum/?fromgroups#!forum/comp.lang.javascript>,
instead of my news reader (Thunderbird), and the post has appeared
twice. So after deleting one of them … Ta-da! both the two posts
disappeared in the guts of the Internet. Thanks Google!
I am answering to what I remembered:

I don't know a Javascript guru Stoyan Stefanov but I am ready to
believe that he is a knowledgeable specialist.

Stoyan Stefanov is the author of the "JavaScript Patterns" and
"Object-Oriented JavaScript" books. Asen Bozhilov reviewed the JS
Patterns book and, thus, you can trust it almost entirely except for
some typos. Stoyan is also the creator of the "smush.it" image
optimization tool and architect of Yahoo's performance optimization tool
YSlow 2.0.

According to Stoyan Stefanov, one of the JS Mentors
<http://jsmentors.com/> too , "the Object() constructor accepts a
parameter and, depending on the value passed, it may decide to delegate
the object creation to another built-in constructor and return a
different object than you expect". Examples copied from JS Patterns book
(by Stoyan Stefanov):

// an empty object
var o = new Object();
console.log(o.constructor === Object); // true

// a number object
var o = new Object(1);
console.log(o.constructor === Number); // true
console.log(o.toFixed(2)); // "1.00"

// a string object
var o = new Object("I am a string");
console.log(o.constructor === String); // true
// normal objects don't have a substring()
// method but string objects do
console.log(typeof o.substring); // "function"

// a boolean object
var o = new Object(true);
console.log(o.constructor === Boolean); // true

In his excellent book, Stoyan also illustrate other reasons to avoid the
new Object(), String(), Number(), Array(), etc. antipattern altogether.

For the Object
constructor matter:

var obj = {}; // Object initialiser

var obj = new Object(); // Object constructor call

var obj = new Object; // Object constructor call w/o parenthesis

are absolutely the same and being processed by the same algorithm in
Javascript. So if someone is really up to for saving keystrokes they
better do it from the right side. :)

The "spooky booh" with new Object(1), new Object("foobar") is
propaganda to disregard. Whatever happens with Object called with
different arguments is written in details in language references. If
it leads to a surprise of a programmer then where is the Javascript
fault? Most importantly OOP is not about creating Object instances. It
is about creating MyObject, MyExtendedObject from MyObject,
MyXtendedObject from MyExtendedObject etc. Unless of course I am
completely off from modern OOP interpretations.

Well, I appreciate your stance about the "new Object" constructor. It
seems sensible. Now I am thinking that this kind of logic in Stoyan's
book (and Douglas Crockford's too) is really a bit of propaganda.

Cheers,
Joao Rodrigues (J.R.)
 
J

John G Harris

On Mon, 18 Apr 2011 at 11:39:47, in comp.lang.javascript, VK wrote:

Though I assume I know from where the stinky wind is blowing. From the
same place maybe where "new operator is considered harmful" and
var obj = {}; // is professional and OK
while
var obj = new Object(); // is unprofessional and harmful

I assume others may also know the location and the name of the
person...

One source is Crockford who says you often forget to type 'new' when
creating a new object. This leads to faults that are difficult to track
down, therefore New Considered Harmful.

John
 
D

David Mark

It's easy enough to use to START a discussion.  And I could probably
live without threading if the view was entirely flat.  But instead
they offer a 2-ply system: you can add a message to the main thread,
or you can offer a comment on a top-level message.  But that's it.
You can't reply to the comments.  It really is the worst of both the
flat and the threaded models!

But it's so pretty!  :)





Although I agree, and that's what I meant by saying that the response
is a little short-sighted, I do understand the reluctance to introduce
a change that might somewhere, somehow break code that's taking
advantage of the current behavior -- especially when there have been
no reports of the current implementation having issues.  But blind
insistence on backward-compatibility is also what leads to Microsoft-
style bloat.  jQuery could use a huge refactoring.  But I can't see
them being willing, now that it's so popular, to take the risk.  The
last time I remember a large breaking change to their public API was
when they dropped XPath support in their selectors.  That was hard
enough, and they were not nearly so popular then.

Clearly you know very little about the history of this most dubious
script. JFTR, they change their public API all the time. Most
recently, they have announced they are going to replace the long-
broken "attr" method with something that works entirely differently.
Yes, that one. They are replacing it with something very similar to
the "attr" found here:-

http://www.cinsoft.net/attributes.html

Of course, that's the sort of brain-dead move I would expect out of
them (three and a half years later). As I've mentioned a thousand
times, the users of that script don't need an "attr" (jQuery needs it
internally). It's like their own name for it threw them off. They
couldn't change the name, so they changed the function to fit the
name. :) As per usual, this is a backwards move. And even more
disturbing, it comes at a time when IE6/7 legacy code is being phased
out of (not into) libraries. Most of the workarounds found on the
above page (and in My Library) are strictly for IE6/7 (and
compatibility mode in later versions, which jQuery has never
"supported" anyway). Same day I announce a new filter for My Library
to optionally pare such code from My Library, jQuery announces they
are finally adding it.

In an HTML DOM (as opposed to XML from an XHR result), which is all
jQuery is capable of dealing with (e.g. no XHTML) and what all of
jQuery's examples use, the much-utilized (and much maligned) "attr"
method retrieves property values by attribute name. Now they are
going to replace that with a function that retrieves attribute values
(which are largely useless and confusing to jQuery users). The "road
map" announcement said something about trying the new "prop" method
(also found on the above page) if the new "attr" method "doesn't
work".

Uhhhhh... This isn't just the stupidest thing they've ever come up
with; it may well be the stupidest idea in history, particularly given
the large and easily confused user base.

And they had almost four years to think about this. :(

What they should have done is deprecate (and later delete) the
removeAttr method. It doesn't go with anything in their history
(certainly not with "attr"). Then they should have fixed the basic
problems with "attr". Yes, it was fixable (just as Dojo's was
fixable). No need to transform it into something entirely different
(and largely unneeded). Then they should have added another function
that dealt with attributes, perhaps keeping it private (for use by the
query engine). Most jQuery users just won't grasp the difference
between the two methods (after all, the jQuery authors never did).
I think he was just a fan-boy.  I haven't seen such attitude from the
core team.

Once again, you are a clueless buffoon...
I'm really mixed about their overloading.  The get/set style
overloading doesn't bother me at all.  But the number of things the
jQuery constructor (and it's `$` alias) does is crazy.

....and pseudo-intellectual parrot.
Maybe, but I don't think it would be enough of a challenge to satisfy
that itch.  ;-p

What would you show off? More ignorance? Still think the "popular"
libraries are best practice? First Dojo died, now this. :)
 
D

David Mark

I'm not sure if that emoticon is to suggest that no one here would
bother.  I would.  I did.  I brought it up on jQuery's developer's
forum here:
and got into a debate with one person who thought this suggestion was
an attempt to prove I'm smart by breaking the code  :) and worried
about the 11 additional source-code characters.  Another member (one
of the core developers) was more interested.  He responded: "I'm not
inclined to change this code since nobody has ever reported a problem
with it.", which IMHO is not unreasonable although perhaps a little
short-sighted.  He also did some research to find out WHY this is
being done this way, but received no real satisfaction.  I wouldn't be
at all surprised to find that after kangax published his article,
someone swept through the JQ code and blindly eliminated all
`instanceof` operators, even if they did not have the relevant cross-
frame issues.

[...]

From the linked thread:

"It was my mistake for even bothering to respond to your post that
proves nothing more then you're lack of respect for a documented API
and how well you can break it. Woo! Congrats!"

This speaks volumes IMO.

Yes, as does this (from the post that references the thread):-

"I'm not inclined to change this code since nobody has ever reported a
problem with it."

So, they don't fix logic problems until users have (and actually
report) issues as a result.

And JFTR, that's not the slightest bit reasonable. It's pure lunacy.

What is it that draws people to use this code, again? Oh, that's
right; it's "popular". :)
 
D

David Mark

Stefan said:
The overall outcome is a little disappointing. I'm not familiar enough
with jQuery to judge the actual impact of this problem... maybe someone
can enlighten me. Did I understand correctly that jQuery plugins can -
and do - add random properties to the main jQuery object, basically
without naming restrictions except to avoid conflicts with the official
jQuery API? In this case, there could well be a problem with a (future)
plugin adding a "preventDefault" property, and it would be better to be
safe than sorry.

There is nothing to prevent users from doing so.  I don't think it's
common to have it happen.  Most plug-ins run against jQuery's wrapped
sets of DOM elements.  But there are a number that add functions to
the jQuery constructor object as well.  That sort could have this
problem.  But I don't think I've ever seen any that are themselves
constructor functions, which is the only case that could trigger this
issue.  But there is nothing to prevent someone from writing one.
For reference, the original code author's comments were
| I'm not 100% sure now, it's been a while. I guess the reasons were:
|
| - cross frame compat
| - Seems simpler (short and clean)
| - There was no instanceof [in some browsers] at that time I think
| - I'm pretty sure I took jQuery.fn.init as a reference which at that
|   time did stuff like that.
"cross frame compat" is of no concern in this case.
"seems simpler" - okay, maybe - "(short and clean)" - it's no longer
clean if it can be a source of unintentional behavior, IMO.

Right, although that was not an issue for anyone until this point was
raised, so it's a reasonable answer to why it was coded thus.

As if you (or they) know that. And what a stupid concept (certainly
not reasonable).
I'm guessing it's simply faulty memory.  "instanceof" was, I'm almost
certain, widely implemented and consistent at that time.

Good guess. Yes, jQuery never claimed to work in any browser that
lacked that operator (so you can be sure it does not).
`jQuery.fn` is just an alias to jQuery.prototype.  `init` is the
actual constructor function used.  Again, I'm guessing there might be
some faulty memory here since, in these days at least, the relevant
code looks like this:

(inside an immediately invoked function expression)
|    var jQuery = function( selector, context ) {
|      return new jQuery.fn.init( selector, context, rootjQuery );
|    },

That code has changed numerous times over the years, reflecting their
typical flail-until-you-hit-something pattern of development.
and the actual `init` function, which is the true constructor, does
not use any similar type checking.


Agreed.  There are many interesting techniques used in the various
libraries.  There is plenty of bad code in all of them, but also code
worth looking at.

So look at whatever you want. How do the posts of others affect what
you look at?
Here's to civil discourse!

Oh shut up.
 
S

Scott Sauyet

VK said:
Because such programming paradigm is explicitly forbidden and on IE/
JScript leads to "Can't execute code from a freed script" run-time
error: yet there are known ways to cheat on this protection.

Huh? If you create an Array, say, in one frame and pass it to
another, then in that other one

otherFramesArray instanceof Array

will return `false`. That's the problem, and it has nothing to do
with any forbidden programming paradigm.
So the message of the author of the linked article
http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
is as read it: "I managed to write a specially crafted code that
allowed me to bypass built-in run-time engine analyzer. By using this
code I managed to force instanceof operator to get dizzy in some
circumstances. Conclusion: instanceof operator considered harmful in
Javascript programming".

Did you actually read the article? I read it very differently. What
it seems to me he said is "There is a significant issue with
`instanceof` and other standard attempts at type-checking, but I've
found another technique which is easy to use and which is guaranteed
to work for a number of built-in types in any ES-engine properly
implementing the standards."

And as far as I can tell his method is sound, although Richard
Cornford did demonstrate an obscure possible bug with it in <https://
groups.google.com/group/comp.lang.javascript/msg/f0bc47f64cc96cce?
hl=en>.

-- Scott
 
D

David Mark

VK  wrote:


Huh?  If you create an Array, say, in one frame and pass it to
another, then in that other one

Yeah, it's easy to look smart standing next to VK. :)
    otherFramesArray instanceof Array

will return `false`.  That's the problem, and it has nothing to do
with any forbidden programming paradigm.


Did you actually read the article?  I read it very differently.  What
it seems to me he said is "There is a significant issue with
`instanceof` and other standard attempts at type-checking, but I've
found another technique which is easy to use and which is guaranteed
to work for a number of built-in types in any ES-engine properly
implementing the standards."

And as far as I can tell his method is sound, although Richard
Cornford did demonstrate an obscure possible bug with it in <https://
groups.google.com/group/comp.lang.javascript/msg/f0bc47f64cc96cce?
hl=en>.

It's not an "obscure, possible bug". It's a well-known issue and
closely related to the problem that the workaround is attempting to
fix. So, not sound. And you never need to do such type checking in
JS anyway. If you find yourself doing it, stop as it is impossible,
as well as unnecessary.

HTH
 

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,774
Messages
2,569,598
Members
45,158
Latest member
Vinay_Kumar Nevatia
Top