On Mar 14, 8:43 pm, Jason Mulligan <[email protected]>
wrote:
> Hi Rob, thanks for looking. It would've been better if you had looked
> at the lib prior to making your comments, for context.

I looked at the code, thoroughly. It would be better if you would
reply below quotes of what you are replying to so that your comments
are in context.

>
> The function returns either a NodeList passed by reference, or an
> instance. An instance is an occurrence or a copy of an object, so it
> should be a valid term; hence you get an instance of the NodeList if
> it's not by reference.

The term "instance" is rarely used in javascript because of its links
to more classic inheritance patterns that are inconsistent with
ECMAScript's. The term instance is sometimes used to indicate an
object was constructed from another object, so given:

  var a = new B();

a might be considered an instance of B. The instanceof operator only
checks that the prototype of the object on the RHS is on the internal
[[prototype]] chain of the one on the left. Given the dynamic nature
of javascript, whether:

  a instanceof B

returns true or false doesn't tell you whether B was used to construct
a (i.e. whether a is an instance of B). So the operator is a bit
useless, which is why you will rarely see an instanceof test.

The classic clone()[1] or beget() function is a common way of creating
a prototype inheritance chain (and avoid using new in other code) and
effectively "share" properties between objects.

In regard to copying, the only meaningful way to copy an object in
ECMAScript is to create a new object and copy one object's enumerable
properties and their values to the other. This is completely different
from an instance of an object, where the relationship is via
[[prototype]].

You might say that getElementsByTagName returns an "instance" of a
NodeList, but strictly it returns a reference to a NodeList. It is
common to just say it returns a NodeList, using the term "instance"
just confuses things. See comments below on element "instances".

> That's one reason I won't choose "elements",
> since it's instances of elements.

No, it's references to elements. And what are elements instances of?
It's a meaningless term the context of a DOM since DOM objects aren't
native ECMAScript objects, you have no idea whether there is any
inheritance (there doesn't seem to be in IE).

All you can say is that an element is an object that implements the
HTMLElement interface, calling it an "instance" infers some kind of
inheritance (even a constructor) that may well not exist, and even if
it did, is not useful for cross browser scripting.

The above is why some prefer to call ECMAScript object based, not
object oriented, so as to make a distinction from the more traditional
object and inheritance patterns.


> I don't plan to reformat my code for this limited thread system; if
> anything i'd rather be that guy that eventually causes an admin to
> rethink their formatting limitations.

It has nothing to do with system administrators, they don't read this
group - the people you want to help you do. So you can help out the
members of the group by posting neatly formatted, ready-to-run code or
you can make helping you more difficult.

If you wish to complain to Google about their auto-formatting, please
do.

Wrapping code at 72 characters (I prefer about 70 to allow for one or
two levels of quoting) is a convention from Usenet, which is where
Google Groups got most of its content to start with. It is still a
very useful convention - shorter lines are easier to read and much
more convenient to work with.


> Picking at the docblock is interesting, it's changed since I posted.

It would be nice to see the new version.

> Again, would've been useful to look at the entire picture.

I looked at what you posted.

> Also,
> assuming that someone knows what's by reference and what isn't, is a
> mistake in my opinion.

It is fundamental to javascript. Anyone using or maintaining your code
who doesn't understand that shouldn't be using or maintaining your
code.

Strictly, everything is passed by value, where some values are
primitives and some are references. But anyone who is beyond absolute
novice understands that objects are passed by reference. Even though
it is not strictly correct, it is the common understanding and
sufficiently accurate for most cases.


> I was thinking about the split op and you have a point about the
> spaces. I'll probably be making that change sometime this week. As for
> the use of $(), why re-invent the wheel? People expect $() today and
> even write their own simple versions. As an example, it's done
> multiple times in the JavaScript Patterns book, for code samples on
> other topics.

$ has different meanings to different people - compare what it does in
Prototype.js to jQuery. Someone reading code with $(...) will first
look to see which library is loaded and try to guess what it does.
Seeing an unfamiliar library means they have no idea what it does and
will go for the documentation (if it's available) or start trolling
through the source to try and work it out.

If they read the documentation and are told it takes a list of ids and
returns a NodeList, they might get completely the wrong idea. But
apparently you've fixed that (so it was a valid comment for the posted
code).


> Arrays are objects, so a typeof() is not a valid test.

In the part of the code you are referring to, arg could refer to
either an array or a string. I was suggesting that instead of using
instanceof to test for an array (which is unreliable, as noted above),
you could instead use typeof for a string, which is absolutely
reliable. The outcome is the same: you've determined whether arg is a
string or an array.

In this particular case it doesn't really matter since the array is
created in the function and instanceof will give the correct result,
but its use should be avoided when there is a perfectly good
alternative - there is a good reason why it is rarely used.


> Recursions allows you get a 2d array within a 2d array. It's a good
> pattern, one I reuse through the lib encase $() returns an array to
> other methods.

You don't have to use recursion to do that, and it's only good if
needed. Every function that uses recursion can be written without it,
and will run faster.

I'm not saying never use recursion, only that it shouldn't be used
unnecessarily. In this case, the non-recursive version is no longer
and will run faster, so there is no benefit from using recursion.


> There is no Array > String > String op occurring. You either have an
> Array that's processed as one, and returns; or you have a potential
> string argument that's cast because it's cast implicitly with the
> following op; putting it up front shows the person what's occurring
> and hopefully they'd understand why with the charAt(). I tried using
> the Array index as [0], but IE doesn't support that (sad face).
>
> The feature testing comments are out of place; look at the lib.

Posted where?

> The
> init() sets up what's missing for IE. Array.prototype.slice() is from
> 1.5, which IE6 supports.

IE 6 doesn't support passing a host object like a NodeList to slice
the way you did. Your code fails in IE 6, and probably later versions
too.

You call document.getElementsByClassName which, based on your above
comments, means you are adding a getElementsByClassName property to
the document object in IE. Adding custom properties to host objects is
a very bad idea, just don't do it.

Lastly, whatever your getElementsByClassName function for IE returns,
it isn't a NodeList (probably an Array), so calling $('.foo', true)
will not return a NodeList, nor will it be live.

In any case, the "major" script libraries have convinced the HTML5
working group to more or less abandon live lists (I think it's a
mistake, but that's life), so there is little point in providing them,
you may as well ditch that option. That, of course, is just my
opinion.


> You need to learn how to love the ternary as an If-Else,

You didn't use it to replace if..else, you replaced a plain if that
was simpler and less code. I will never love it for that. I didn't
disagree with its use elsewhere.

If you like using certain patterns purely for the sake of it, consider
Crockford's "guard" pattern:

 !nodelist && obj = Array.prototype.slice.call(obj);

which still fails in IE but will keep the novices in awe.


> it doesn't
> have to set a value. What I did is legal, hence no hating it.

The ternary operator is for convenience instead of an if..else block,
using it to conditionally execute an expression instead of a much
simpler if test makes no sense.

The if test suggested as a replacement is simpler, faster and less
code. Using a ternary operator for the same thing can't be
recommended.


> Now, the real input I was after... Why do you think iteration is
> better than casting with slice()? That seems like true wasted cycles
> to me, and I was hoping for some deep thought on it. Since slice is
> just an expression; I haven't had time to dig to see what it's really
> doing. Is it a simple 1 liner to the same iteration?

Because passing a host object like that will fail in some browsers,
specifically IE 6 and likely others too. You can't treat host objects
as if they are native objects.


> There's no reason why a switch can't be compiled to be faster than an
> if-else, look at PHP's switch(true){} .. complete 180 in performance
> from 4.0 to 5.2+

I didn't comment on the use switch. Performance is not a reason to use
one or the other, one might be faster in some browsers and slower in
others. I used if..else in my example because I think it's neater.

1. <URL: 
http://groups.google.com/group/comp.lang.javascript/msg/5d06e72e55d5bf11
>


--
Rob

-- 
To view archived discussions from the original JSMentors Mailman list: 
http://www.mail-archive.com/[email protected]/

To search via a non-Google archive, visit here: 
http://www.mail-archive.com/[email protected]/

To unsubscribe from this group, send email to
[email protected]

Reply via email to