The Prototype library gives us the $() operation for converting a DOM element id into the DOM element: $('element-id'). It also appends a bunch of functions to the resulting object.
Sometimes though, passing a string into the $() function doesn't read well; and only makes Javascript code harder to read. For example: $(window.button_list()[3]).hide()
Instead, it'd be nice to have normal chainability. I like the following syntax: window.button_list()[3].$().hide().
That is, call the $() method on a string object, instead of passing the string into the $() method.
> Sometimes though, passing a string into the $() function doesn't read > well; and only makes Javascript code harder to read. For example: > $(window.button_list()[3]).hide()
Actually, this is widely acclaimed as a nice way to do it. Of course, there's no accounting for taste, but it is nicely unobstrusive, which is the whole point of choosing such a short name.
> Instead, it'd be nice to have normal chainability. I like the > following syntax: window.button_list()[3].$().hide().
Suit your taste, it's pretty easy to do so. But I don't think I dare too much in asserting this will *not* happen in the official codebase.
I agree, and I still use the $('element-id') version in most places. I found 'element-id'.$() reads well within a line of complex code where it becomes less obvious what the $(...) is enveloping.
Cheers Nic
On 9/11/06, Christophe Porteneuve aka TDD <t...@tddsworld.com> wrote:
> Dr Nic a écrit : > > Sometimes though, passing a string into the $() function doesn't read > > well; and only makes Javascript code harder to read. For example: > > $(window.button_list()[3]).hide()
> Actually, this is widely acclaimed as a nice way to do it. Of course, > there's no accounting for taste, but it is nicely unobstrusive, which is > the whole point of choosing such a short name.
> > Instead, it'd be nice to have normal chainability. I like the > > following syntax: window.button_list()[3].$().hide().
> Suit your taste, it's pretty easy to do so. But I don't think I dare > too much in asserting this will *not* happen in the official codebase.
-- Dr Nic Williams http://www.drnicwilliams.com - Ruby/Rails blog skype: nicwilliams (m) +31 62 494 8552 (p) +61 7 3102 3237 (finds me anywhere in the world) (f) +61 7 3305 7572 (sends fax to my email)
> The Prototype library gives us the $() operation for converting a DOM > element id into the DOM element: $('element-id'). It also appends a > bunch of functions to the resulting object.
> Sometimes though, passing a string into the $() function doesn't read > well; and only makes Javascript code harder to read. For example: > $(window.button_list()[3]).hide()
> Instead, it'd be nice to have normal chainability. I like the > following syntax: window.button_list()[3].$().hide().
> That is, call the $() method on a string object, instead of passing > the > string into the $() method.
> > The Prototype library gives us the $() operation for converting a DOM > > element id into the DOM element: $('element-id'). It also appends a > > bunch of functions to the resulting object.
> > Sometimes though, passing a string into the $() function doesn't read > > well; and only makes Javascript code harder to read. For example: > > $(window.button_list()[3]).hide()
> > Instead, it'd be nice to have normal chainability. I like the > > following syntax: window.button_list()[3].$().hide().
> > That is, call the $() method on a string object, instead of passing > > the > > string into the $() method.
-- Dr Nic Williams http://www.drnicwilliams.com - Ruby/Rails blog skype: nicwilliams (m) +31 62 494 8552 (p) +61 7 3102 3237 (finds me anywhere in the world) (f) +61 7 3305 7572 (sends fax to my email)
> > The Prototype library gives us the $() operation for converting a > DOM > > element id into the DOM element: $('element-id'). It also appends a > > bunch of functions to the resulting object.
> > Sometimes though, passing a string into the $() function doesn't > read > > well; and only makes Javascript code harder to read. For example: > > $(window.button_list()[3]).hide()
> > Instead, it'd be nice to have normal chainability. I like the > > following syntax: window.button_list()[3].$().hide().
> > That is, call the $() method on a string object, instead of passing > > the > > string into the $() method.
Not sure what this proves, except that the function returns a thing with a type "object" rather than type "string". The way firebug displays things probably depends on the result of typeof, and arrays give "object", so Firebug thinks it's an array. Or something like that.
> Not sure what this proves, except that the function returns a thing with > a type "object" rather than type "string". The way firebug displays > things probably depends on the result of typeof, and arrays give > "object", so Firebug thinks it's an array. Or something like that.
> Chris
-- Dr Nic Williams http://www.drnicwilliams.com - Ruby/Rails blog skype: nicwilliams (m) +31 62 494 8552 (p) +61 7 3102 3237 (finds me anywhere in the world) (f) +61 7 3305 7572 (sends fax to my email)
Yeah, the issue with your original implementation is due to this test in Prototype's $:
if (typeof element == "string")
When you refer to yourself, as a String, using this, typeof says "object". A more reference-proof way of testing whether you actually are a string would be to say:
if (element.constructor === String)
Using this:
function $() { var results = [], element; for (var i = 0; i < arguments.length; i++) { element = arguments[i]; if (element.constructor === String) { element = document.getElementById(element); } results.push(Element.extend(element)); } return results.reduce();
> Yeah, the issue with your original implementation is due to this test in > Prototype's $:
> if (typeof element == "string")
> When you refer to yourself, as a String, using this, typeof says > "object". A more reference-proof way of testing whether you actually > are a string would be to say:
> if (element.constructor === String)
> Using this:
> function $() { > var results = [], element; > for (var i = 0; i < arguments.length; i++) { > element = arguments[i]; > if (element.constructor === String) { > element = document.getElementById(element); > } > results.push(Element.extend(element)); > } > return results.reduce(); > }
> -- > Christophe Porteneuve a.k.a. TDD > "[They] did not know it was impossible, so they did it." --Mark Twain > Email: t...@tddsworld.com
-- Dr Nic Williams http://www.drnicwilliams.com - Ruby/Rails blog skype: nicwilliams (m) +31 62 494 8552 (p) +61 7 3102 3237 (finds me anywhere in the world) (f) +61 7 3305 7572 (sends fax to my email)
> -- > Christophe Porteneuve a.k.a. TDD > "[They] did not know it was impossible, so they did it." --Mark Twain > Email: t...@tddsworld.com
-- Dr Nic Williams http://www.drnicwilliams.com - Ruby/Rails blog skype: nicwilliams (m) +31 62 494 8552 (p) +61 7 3102 3237 (finds me anywhere in the world) (f) +61 7 3305 7572 (sends fax to my email)
On 9/11/06, Nic Williams <drnicwilli...@gmail.com> wrote:
> So would it still be useful for a revised $() function?
There is no need to change $().
What you see is the legacy of Netscape taking a stride away from the ECMAScript standard.
Netscape's JS engine treated (and still treats) strings as array of strings to allow things like "test"[0] to return "t".
I do not know the internal working, but from observation:
When using "this" in a function defined in String.prototype, "this" behaves like a string, when the context of the use requires a string. And it looks like the engine knows document.getElementById() requires a string. If the context does not require a string, like when using "this" as a function argument to a user defined function, "this" evaluates to an array of chars.
Therefore, the error is not with $(). Besides the before mentioned $(String(this)), $(this.valueOf()) will work as well.
There has been a previous thread on the overuse of $ type functions. I can't remember how long ago that was.... 3-4 months?? Sorry, I don't have any more information about that though.
On 9/11/06, Dr Nic <drnicwilli...@gmail.com> wrote:
-- Dr Nic Williams http://www.drnicwilliams.com - Ruby/Rails blog skype: nicwilliams (m) +31 62 494 8552 (p) +61 7 3102 3237 (finds me anywhere in the world) (f) +61 7 3305 7572 (sends fax to my email)
> This breaks the "Object is an empty container and can be safely looped > with for( in )" convention.
Aside from the '$ overuse' issue, for/in indeed doesn't work too good on Prototype-extended objects, what with all the methods. Which is precisely why we now have Object.keys(). You would replace for/in with Object.keys().each, I guess.
-- Christophe Porteneuve a.k.a. TDD "[They] did not know it was impossible, so they did it." --Mark Twain Email: t...@tddsworld.com
On 9/12/06, Christophe Porteneuve <t...@tddsworld.com> wrote:
> Aside from the '$ overuse' issue, for/in indeed doesn't work too good on > Prototype-extended objects, what with all the methods.
for ( in ) loops are supposed to work with Objects and they do flawlessly. This is why Object.prototype is not tempered with. for ( in ) loops do not make sense for the other native data types, and user defined classes can't mark properties non-enumerable anyway (a ECMAScript omission), so for ( in ) can only be used for introspection on them.
Object.keys() is not there because for ( in ) does not work (it does), it is a syntactic sugar. If you look at the implementation, it is just a for ( in ) loop. If it would not work properly, Object.keys() could not have used it, obviously.