Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #31082 > unrolled thread
| Started by | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| First post | 2016-08-06 14:25 +1000 |
| Last post | 2016-08-06 10:28 +0200 |
| Articles | 13 — 5 participants |
Back to article view | Back to comp.lang.javascript
filter queryselectorall Andrew Poulos <ap_prog@hotmail.com> - 2016-08-06 14:25 +1000
Re: filter queryselectorall "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2016-08-05 22:23 -0700
Re: filter queryselectorall Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-08-06 08:16 +0200
Re: filter queryselectorall "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2016-08-06 15:49 -0700
Re: filter queryselectorall Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-08-07 07:08 +0200
Re: filter queryselectorall Cezary Tomczyk <cezary.tomczyk@gmail.com> - 2016-08-07 07:17 +0200
Re: filter queryselectorall Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-08-07 07:58 +0200
Re: filter queryselectorall "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2016-08-07 10:30 -0700
Re: filter queryselectorall Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-08-07 21:16 +0200
Re: filter queryselectorall "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2016-08-09 21:18 -0700
Re: filter queryselectorall Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2016-08-15 22:02 +0200
Re: filter queryselectorall "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2016-08-15 23:16 -0700
Re: filter queryselectorall "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-08-06 10:28 +0200
| From | Andrew Poulos <ap_prog@hotmail.com> |
|---|---|
| Date | 2016-08-06 14:25 +1000 |
| Subject | filter queryselectorall |
| Message-ID | <b-Cdnanqh8Yn-zjKnZ2dnUU7-RnNnZ2d@westnet.com.au> |
I have a number of DIV elements many of which start with the ID
"clickable_" and end with either an integer or some alphabetic characters.
I need to only select those that end with an integer. I can get the ones
that start with "clickable_" using
var clickables = document.querySelectorAll('[id^="clickable_"]');
but when I try to filter it further I get stuck.
var clickables = document.querySelectorAll('[id^="clickable_"]').filter(
function() {
return this.id.match(/_\d*$/);
});
gives me ...filter is not a function.
How can I get just the elements whose ID that starts with "clickable_"
and ends with an integer?
Andrew Poulos
[toc] | [next] | [standalone]
| From | "Michael Haufe (TNO)" <tno@thenewobjective.com> |
|---|---|
| Date | 2016-08-05 22:23 -0700 |
| Message-ID | <e5c7c7d6-59fb-489a-bf33-cea363488a6c@googlegroups.com> |
| In reply to | #31082 |
On Friday, August 5, 2016 at 11:25:40 PM UTC-5, Andrew Poulos wrote:
> I have a number of DIV elements many of which start with the ID
> "clickable_" and end with either an integer or some alphabetic characters.
>
> I need to only select those that end with an integer. I can get the ones
> that start with "clickable_" using
>
> var clickables = document.querySelectorAll('[id^="clickable_"]');
>
> but when I try to filter it further I get stuck.
>
> var clickables = document.querySelectorAll('[id^="clickable_"]').filter(
> function() {
> return this.id.match(/_\d*$/);
> });
>
> gives me ...filter is not a function.
>
> How can I get just the elements whose ID that starts with "clickable_"
> and ends with an integer?
querySelectorAll does not return an Array. It returns a NodeList. You'll want to convert it to an array proper first:
let qsa = (s,ctx=document) => Array.from(ctx.querySelectorAll(s))
polyFill as necessary for your target environments, or use a JS compiler such as Babel or TypeScript
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-08-06 08:16 +0200 |
| Message-ID | <1547678.NO00hCYTYS@PointedEars.de> |
| In reply to | #31083 |
Michael Haufe (TNO) wrote:
> On Friday, August 5, 2016 at 11:25:40 PM UTC-5, Andrew Poulos wrote:
>> var clickables = document.querySelectorAll('[id^="clickable_"]').filter(
>> function() {
>> return this.id.match(/_\d*$/);
>> });
>>
>> gives me ...filter is not a function.
>>
>> How can I get just the elements whose ID that starts with "clickable_"
>> and ends with an integer?
Your approach would, if it worked verbatim, find elements with IDs
“clickable__” and “clickable__2”, too. You have made the integer *optional*
with the “*” and you have not excluded consecutive “_”s.
“this” does _not_ refer to the current element in an
Array.prototype.filter() loop callback, but to the global object in normal
mode, and it is “undefined” in strict mode, by default; you can set “this”
with the second argument of .filter(), but obviously not to the current
element in the loop, too.
(AISB:) String.prototype.match() is _not_ the proper method to use if you
only want to *test* *if* a string matches a regular expression. In that
case, use RegExp.prototype.test() instead; an additional advantage of it is
that it converts the argument to String, whereas you have to typecast to
String explicitly (or use "".match.call() or "".match.apply()) if you want
to call String.prototype.match() on a value that you cannot be sure is a
String value.
> querySelectorAll does not return an Array. It returns a NodeList. You'll
> want to convert it to an array proper first:
>
> let qsa = (s,ctx=document) => Array.from(ctx.querySelectorAll(s))
>
> polyFill as necessary for your target environments, or use a JS compiler
> such as Babel or TypeScript
That is taking a sledgehammer to crack a nut.
Instead:
var clickables = [].filter.call(
document.querySelectorAll('[id^="clickable_"]'),
function (element) { return /_\d+$/.test(element.id); });
Alternatively:
var clickables = [].filter.call(
document.getElementsByTagName("*"),
function (element) { return /^clickable_.*\d+$/.test(element.id); });
To mark and find suitable elements, consider using a “data-clickable”
attribute as a marker and to filter on that attribute using the above,
instead. Where that is not Valid (e.g. HTML < 5, default XHTML < 5),
consider using a “js-clickable” class as a marker and
document.getElementsByClassName("js-clickable") instead (the “js-” prefix
makes sure your script-related classes do not interfere with classes that
you use for styling; it is intended to work like a namespace).
Reconsider your search context. Do you really need to search the whole
document?
If, e.g., this is for a form, consider using form.elements["clickable"] or
form.getElementsByName("clickable") [may find more elements than the former]
to find all elements with name "clickable" instead.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | "Michael Haufe (TNO)" <tno@thenewobjective.com> |
|---|---|
| Date | 2016-08-06 15:49 -0700 |
| Message-ID | <a97c4abf-b135-4054-a9b2-55e0190cd1d0@googlegroups.com> |
| In reply to | #31084 |
Thomas 'PointedEars' Lahn wrote:
> Michael Haufe (TNO) wrote:
> > querySelectorAll does not return an Array. It returns a NodeList. You'll
> > want to convert it to an array proper first:
> >
> > let qsa = (s,ctx=document) => Array.from(ctx.querySelectorAll(s))
> >
> > polyFill as necessary for your target environments, or use a JS compiler
> > such as Babel or TypeScript
>
> That is taking a sledgehammer to crack a nut.
More like a pin-hammer. This is a general solution to the problem of manipulating NodeLists, not solving this particular problem. The alternative formulation, to avoid a potential compilation step for down-rev environments would be:
function qsa(s,ctx){return [].slice.call((ctx||document).querySelectorAll(s))}
But is a more low-level[1] solution.
> Instead:
>
> var clickables = [].filter.call(
> document.querySelectorAll('[id^="clickable_"]'),
> function (element) { return /_\d+$/.test(element.id); });
>
Using the form above:
var clickables = qsa('[id^="clickable_"]').filter(e => /_\d+$/.test(e.id))
> To mark and find suitable elements, consider using a “data-clickable”
> attribute as a marker and to filter on that attribute using the above,
> instead.
Agreed.
[1] Anything that requires you to pay attention to the irrelevant is considered low level
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-08-07 07:08 +0200 |
| Message-ID | <1546201.XMfzL8yDUt@PointedEars.de> |
| In reply to | #31090 |
Michael Haufe (TNO) wrote:
> More like a pin-hammer. This is a general solution to the problem of
> manipulating NodeLists, not solving this particular problem. The
> alternative formulation, to avoid a potential compilation step for
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
How so?
> down-rev environments would be:
>
> function qsa(s,ctx){return
> [].slice.call((ctx||document).querySelectorAll(s))}
>
> But is a more low-level[1] solution.
>
>> Instead:
>>
>> var clickables = [].filter.call(
>> document.querySelectorAll('[id^="clickable_"]'),
>> function (element) { return /_\d+$/.test(element.id); });
>
> Using the form above:
>
> var clickables = qsa('[id^="clickable_"]').filter(e => /_\d+$/.test(e.id))
Yes, but one problem with converting a NodeList into an Array is that
NodeLists are live; Arrays are not. Applying an Array prototype method on a
NodeList directly is guaranteed to iterate over all items if matching items
are added while the loop is running, or not iterated over if they are
removed before iteration has reached them.
Another problem is creating an Array instance unnecessarily. (“[].filter”
is just the short form. Creation of an Array instance before filtering can
be avoided entirely by holding the value of “Array.prototype” or
“Array.prototype.filter” in a variable and re-using it as needed.)
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Cezary Tomczyk <cezary.tomczyk@gmail.com> |
|---|---|
| Date | 2016-08-07 07:17 +0200 |
| Message-ID | <bf95c$57a6c473$5ee5db9e$18911@nntpswitch.blueworldhosting.com> |
| In reply to | #31091 |
On 07/08/2016 07:08, Thomas 'PointedEars' Lahn wrote:
> Michael Haufe (TNO) wrote:
[...]
>>> Instead:
>>>
>>> var clickables = [].filter.call(
>>> document.querySelectorAll('[id^="clickable_"]'),
>>> function (element) { return /_\d+$/.test(element.id); });
>>
>> Using the form above:
>>
>> var clickables = qsa('[id^="clickable_"]').filter(e => /_\d+$/.test(e.id))
>
> Yes, but one problem with converting a NodeList into an Array is that
> NodeLists are live;
[...]
querySelectorAll returns a non-live NodeList.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
--
Cezary Tomczyk
http://www.ctomczyk.pl/
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-08-07 07:58 +0200 |
| Message-ID | <12083858.55z44J2QHZ@PointedEars.de> |
| In reply to | #31092 |
Cezary Tomczyk wrote: > On 07/08/2016 07:08, Thomas 'PointedEars' Lahn wrote: >> […] one problem with converting a NodeList into an Array is that >> NodeLists are live; […] > > querySelectorAll returns a non-live NodeList. > > https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll See also: <http://www.w3.org/TR/2013/REC-selectors-api-20130221/#interface-definitions> Thanks. That solves this particular problem in this particular case. -- PointedEars FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/> Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix> Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | "Michael Haufe (TNO)" <tno@thenewobjective.com> |
|---|---|
| Date | 2016-08-07 10:30 -0700 |
| Message-ID | <792aba7d-dad5-48f2-abbc-08beaf9a69ad@googlegroups.com> |
| In reply to | #31091 |
On Sunday, August 7, 2016 at 12:08:43 AM UTC-5, Thomas 'PointedEars' Lahn wrote: > Michael Haufe (TNO) wrote: > > > More like a pin-hammer. This is a general solution to the problem of > > manipulating NodeLists, not solving this particular problem. The > > alternative formulation, to avoid a potential compilation step for > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > How so? The common habit is to write JavaScript to target the least common denominator of support: namely ES3 or ES5. Hence my example and more-so yours. I take the position that one should write in the latest standard version and compile to the lowest common denominator instead. Web Developers aren't quite there yet in their personal workflow though and many common libs may not be prepared properly for use (using global variables and fake namespaces vs. modules). > Another problem is creating an Array instance unnecessarily. (“[].filter” > is just the short form. Creation of an Array instance before filtering can > be avoided entirely by holding the value of “Array.prototype” or > “Array.prototype.filter” in a variable and re-using it as needed.) I would rather defer to Array.from, but yes, if I wanted to micro-optize: var filter = (xs,fn) => Array.prototype.filter.call(xs,fn) var isEven = (x) => x % 2 == 0 var xs = [1,2,3,4,5] filter(xs,isEven) /* 2,4 */ Even better if the standards bodies would align better and fix this mess of an inheritance model. NodeList extends Array or somesuch...
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-08-07 21:16 +0200 |
| Message-ID | <1753248.oMNUckLgyt@PointedEars.de> |
| In reply to | #31094 |
Michael Haufe (TNO) wrote:
> […] Thomas 'PointedEars' Lahn wrote:
>> Michael Haufe (TNO) wrote:
>> > More like a pin-hammer. This is a general solution to the problem of
>> > manipulating NodeLists, not solving this particular problem. The
>> > alternative formulation, to avoid a potential compilation step for
>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> How so?
>
> The common habit is to write JavaScript to target the least common
> denominator of support: namely ES3 or ES5. Hence my example and more-so
> yours.
Those are *examples*. Unless news syntax is concerned (and even then, but
at the cost of runtime efficiency and perhaps even security – eval(…)),
there is no requirement to target the least common denominator: with proper
feature testing, one can support *all* implementations suitable in that
regard. Indeed, unless determining support is the goal, it is usually
better to “polyfill” and use the polyfill so that the polyfill can be
removed once all target environments support the native feature. (This
recommendation does not apply to host objects.)
> I take the position that one should write in the latest standard
> version and compile to the lowest common denominator instead. Web
> Developers aren't quite there yet in their personal workflow though and
> many common libs may not be prepared properly for use (using global
> variables and fake namespaces vs. modules).
We have discussed this elsewhere and disagree about this. I do not think it
is a good idea to use the latest/an extended version of a programming
language just for the sake of it. Code that needs to be transpiled to
backwards-compatible code not only adds the transpiler as a dependency; it
can be a lot less efficient than if a simpler, more traditional pattern had
been used that would not require a transpiler. One must ask oneself the
question if the “syntactic sugar” is really worth it.
>> Another problem is creating an Array instance unnecessarily.
>> (“[].filter” is just the short form. Creation of an Array instance
>> before filtering can be avoided entirely by holding the value of
>> “Array.prototype” or “Array.prototype.filter” in a variable and re-using
>> it as needed.)
>
> I would rather defer to Array.from, but yes, if I wanted to micro-optize:
>
> var filter = (xs,fn) => Array.prototype.filter.call(xs,fn)
[For example, I found the advantage of that syntax over
var filter = function (xs, fn) {
return Array.prototype.filter.call(xs, fn);
}
to be negligibly small. The latter is even clearer than the former: I do
not have to look closely to know that .filter() is not .call()ed before
the anonymous function is called.]
In any case, this is not a good idea because it requires resolution of
“Array.prototype.filter” along the scope chain every time the filter
function is called. It is not micro-optimization, but *de*optimization.
Use instead:
/* cache _once_ */
var filter = Array.prototype.filter;
> var isEven = (x) => x % 2 == 0
> var xs = [1,2,3,4,5]
> filter(xs,isEven)
filter.call(xs, isEven);
> /* 2,4 */
>
> Even better if the standards bodies would align better and fix this mess
> of an inheritance model.
>
> NodeList extends Array or somesuch...
We (but IIRC not the two of us) have discussed this before. The DOM is
designed to be a *language-independent* API, therefore it does not make
sense for a DOM *interface* to extend a *prototype* of *one* particular
programming language (here: ECMAScript).
Historically, the DOM approach has been the other way around: Language
binding was specified so that in certain programming languages features of
the DOM were easier to use. For example, if “list” refers to an object
implementing the NodeList interface, you can write “list[1]” instead of
“list.item(1)” in ECMAScript implementations because the language binding
section of the DOM Specification says so.
<https://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html>
However, the goals of DOM4 (REC as of 2015-11-19) explicitly include
,-<https://www.w3.org/TR/2015/REC-dom-20151119/#goals>
|
| · Aligning [previous Web API Specifications] with the JavaScript ecosystem
| where possible.
and DOM4 calls DOM Level 3 Core “non-normative”. That would include the
ECMAScript Language Binding.
The aforementioned simplification is no longer specified by language binding
in DOM4 but simply as alternative syntax (with no reference to “JavaScript”
whatsoever). (From this we can assume that inheritance from Array.prototype
was not possible if the DOM was to be kept language-indepent.)
Now, DOM *implementations* MAY decide to implement the inheritance that you
wish for. But be careful what you wish for: This would create a potential
for naming conflicts when the DOM interface specifies attributes or methods
whose names are already in use in ECMAScript or the document. For
HTMLCollection the situation is worse than NodeList as a conforming
ECMAScript implementation must not distinguish between property access by
brackets and by dot, which DOM2+ allow instead of calling the .namedItem()
method with the name/ID as argument.
Even if “the standards bodies would align better” they could not solve the
problem of unforeseen element names or IDs to the satisfaction of all people
involved: for example, if HTMLCollection inherited from Array.prototype,
none of the names of inherited properties could be used as element names or
IDs by authors; otherwise they would override those attributes and methods.
Such misguided attempts by API designers have already been made and the
mistakes are still causing problems today: because of
HTMLFormElement::submit() and the “form.elements["bar"] → form.bar” access
shortcut introduced in DOM Level 0, one must not name any control in that
form "submit" or the method becomes unavailable; even removing such an
element on submit does not restore the method, but leaves the property value
to be “undefined”; IOW, not callable.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | "Michael Haufe (TNO)" <tno@thenewobjective.com> |
|---|---|
| Date | 2016-08-09 21:18 -0700 |
| Message-ID | <1d8bd139-924d-416d-8d4b-a27d52a9e348@googlegroups.com> |
| In reply to | #31095 |
Thomas 'PointedEars' Lahn wrote:
> [...]
> Indeed, unless determining support is the goal, it is usually
> better to “polyfill” and use the polyfill so that the polyfill can be
> removed once all target environments support the native feature. (This
> recommendation does not apply to host objects.)
Assuming what you "polyfill" can be done 100% of course. If you can't, I'd point towards the decorator pattern instead.
> Michael Haufe (TNO) wrote:
> > I take the position that one should write in the latest standard
> > version and compile to the lowest common denominator instead. Web
> > Developers aren't quite there yet in their personal workflow though and
> > many common libs may not be prepared properly for use (using global
> > variables and fake namespaces vs. modules).
>
> We have discussed this elsewhere and disagree about this. I do not think it
> is a good idea to use the latest/an extended version of a programming
> language just for the sake of it.
"just for the sake of it"? I think there is something behind this you could expand on.
> Code that needs to be transpiled to
> backwards-compatible code not only adds the transpiler as a dependency; it
> can be a lot less efficient than if a simpler, more traditional pattern had
> been used that would not require a transpiler. One must ask oneself the
> question if the “syntactic sugar” is really worth it.
I'm not criticizing you for this specifically, it's more of a nit I have:
I never really understood the fascination with the word "transpiler" I see it as yet another buzzword like "polyfill" I wish didn't exist due to all the baggage associated.
I'd rather people kept with "compiler".
Which of these counts as "transpilation" vs. "compilation"?
ES6 -> ES6 (minified)
ES6 -> ES5
ES6 -> ES3
ES6 -> asm.js
> Michael Haufe (TNO) wrote:
> > I would rather defer to Array.from, but yes, if I wanted to micro-optize:
> >
> > var filter = (xs,fn) => Array.prototype.filter.call(xs,fn)
Thomas 'PointedEars' Lahn wrote:
> [For example, I found the advantage of that syntax over
>
> var filter = function (xs, fn) {
> return Array.prototype.filter.call(xs, fn);
> }
>
> to be negligibly small. The latter is even clearer than the former: I do
> not have to look closely to know that .filter() is not .call()ed before
> the anonymous function is called.]
If you dislike it as being too terse, fair enough. I assume you know that the semantics of "function(){...this...}" differ from "() => {...this...}"
> In any case, this is not a good idea because it requires resolution of
> “Array.prototype.filter” along the scope chain every time the filter
> function is called. It is not micro-optimization, but *de*optimization.
Assuming the Tracing JIT doesn't do its job... [1]
Thomas 'PointedEars' Lahn wrote:
> Michael Haufe (TNO) wrote:
> > Even better if the standards bodies would align better and fix this mess
> > of an inheritance model.
> >
> > NodeList extends Array or somesuch...
>
> We (but IIRC not the two of us) have discussed this before.
Indeed, we haven't directly, but it's worth enumerating again.
> The DOM is
> designed to be a *language-independent* API, therefore it does not make
> sense for a DOM *interface* to extend a *prototype* of *one* particular
> programming language (here: ECMAScript).
>
> Historically, the DOM approach has been the other way around: Language
> binding was specified so that in certain programming languages features of
> the DOM were easier to use. For example, if “list” refers to an object
> implementing the NodeList interface, you can write “list[1]” instead of
> “list.item(1)” in ECMAScript implementations because the language binding
> section of the DOM Specification says so.
>
> <https://www.w3.org/TR/DOM-Level-3-Core/ecma-script-binding.html>
>
> However, the goals of DOM4 (REC as of 2015-11-19) explicitly include
>
> ,-<https://www.w3.org/TR/2015/REC-dom-20151119/#goals>
> |
> | · Aligning [previous Web API Specifications] with the JavaScript ecosystem
> | where possible.
>
> and DOM4 calls DOM Level 3 Core “non-normative”. That would include the
> ECMAScript Language Binding.
>
> The aforementioned simplification is no longer specified by language binding
> in DOM4 but simply as alternative syntax (with no reference to “JavaScript”
> whatsoever). (From this we can assume that inheritance from Array.prototype
> was not possible if the DOM was to be kept language-indepent.)
JavaScript isn't expressive enough (Yet?) to define the constraints and intent properly anyway. (interfaces and such)
> Now, DOM *implementations* MAY decide to implement the inheritance that you
> wish for. But be careful what you wish for: This would create a potential
> for naming conflicts when the DOM interface specifies attributes or methods
> whose names are already in use in ECMAScript or the document. For
> HTMLCollection the situation is worse than NodeList as a conforming
> ECMAScript implementation must not distinguish between property access by
> brackets and by dot, which DOM2+ allow instead of calling the .namedItem()
> method with the name/ID as argument.
>
> Even if “the standards bodies would align better” they could not solve the
> problem of unforeseen element names or IDs to the satisfaction of all people
> involved: for example, if HTMLCollection inherited from Array.prototype,
> none of the names of inherited properties could be used as element names or
> IDs by authors; otherwise they would override those attributes and methods.
>
> Such misguided attempts by API designers have already been made and the
> mistakes are still causing problems today: because of
> HTMLFormElement::submit() and the “form.elements["bar"] → form.bar” access
> shortcut introduced in DOM Level 0, one must not name any control in that
> form "submit" or the method becomes unavailable; even removing such an
> element on submit does not restore the method, but leaves the property value
> to be “undefined”; IOW, not callable.
Frankly, after 20 some odd years of me living/developing in this web world, I don't care too much anymore about the evolution of these standard bodies. The passion is gone and there's nothing new under the sun AFAIC. No more archaeology, and no more bazaars as far as I can manage. The cathedral is where I trek. [2][3]
[1] <https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JIT_Optimization_Strategies>
[2] "A Generation Lost in the Bazaar" <http://queue.acm.org/detail.cfm?id=2349257>
[3] Alan Kay: '
Is it really "Complex"? Or did we just make it "Complicated"?'
<https://www.youtube.com/watch?v=ubaX1Smg6pY>
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2016-08-15 22:02 +0200 |
| Message-ID | <4229720.31r3eYUQgx@PointedEars.de> |
| In reply to | #31101 |
Michael Haufe (TNO) wrote:
> Thomas 'PointedEars' Lahn wrote:
>> Michael Haufe (TNO) wrote:
>> [...]
>> Indeed, unless determining support is the goal, it is usually
>> better to “polyfill” and use the polyfill so that the polyfill can be
>> removed once all target environments support the native feature. (This
>> recommendation does not apply to host objects.)
>
> Assuming what you "polyfill" can be done 100% of course. If you can't, I'd
> point towards the decorator pattern instead.
ACK.
>> > I take the position that one should write in the latest standard
>> > version and compile to the lowest common denominator instead. Web
>> > Developers aren't quite there yet in their personal workflow though and
>> > many common libs may not be prepared properly for use (using global
>> > variables and fake namespaces vs. modules).
>> We have discussed this elsewhere and disagree about this. I do not think
>> it is a good idea to use the latest/an extended version of a programming
>> language just for the sake of it.
>
> "just for the sake of it"? I think there is something behind this you
> could expand on.
Because it’s “cool” to use it, not because there is considerable *tangible*
benefit in using it.
> I never really understood the fascination with the word "transpiler" I see
> it as yet another buzzword like "polyfill" I wish didn't exist due to all
> the baggage associated.
>
> I'd rather people kept with "compiler".
There is a difference. “Transpiler” is in fact a not-so-new [1] portmanteau
standing for “transcoding compiler” which in turn stands in for “translating
source-to-source compiler”. The difference is that a compiler usually does
not generate source code, but *machine* code.
<https://en.wikipedia.org/wiki/Source-to-source_compiler>
[1]
<https://www.google.com/search?q=transpiler&safe=active&source=lnt&tbs=cdr%3A1%2Ccd_min%3A01.01.1960%2Ccd_max%3A31.12.2000&tbm=>
(The Google Books Ngram Viewer at <https://books.google.com/ngrams> did not
have “transpiler”, so I tried a time-based Google Search.)
> Which of these counts as "transpilation" vs. "compilation"?
>
> ES6 -> ES6 (minified)
That does not count either as transpilation or compilation in my book
because the underlying programming language stays the same. Therefore the
proper term is, obviously, “minification” or “minifying”, which I would
categorize as a form of automated refactoring, and define as refactoring in
order to generate equivalent source code that is as small as possible.
> ES6 -> ES5
> ES6 -> ES3
It is debatable whether that alone can be called transpilation because one
could argue that the underlying programming language stays the same
(ECMAScript), only that the resulting source code is executable by an
implementation of an earlier specification of it. However, usually the
software that does this conversion does more than just that (I am thinking
of the TypeScript compiler as an example).
> ES6 -> asm.js
Is there such a thing? If yes, see above, as asm.js is “an extraordinarily
optimizable, low-level subset of JavaScript”, according to its Web site, and
“a strict subset of JavaScript” according to its Specification (August
2014[!] Working Draft).
BTW, I recently noticed that the 7th Edition of the ECMAScript Language
Specification, ECMAScript 2016, has been published in 2016-06. The HTML
version is available at <http://ecma-international.org/ecma-262/7.0/>.
It should be noted that
| [that] ECMAScript specification is the first ECMAScript edition released
| under Ecma TC39's new yearly release cadence and open development process.
| A plain-text source document was built from the ECMAScript 2015 source
| document to serve as the base for further development entirely on GitHub.
| Over the year of this standard's development, hundreds of pull requests
| and issues were filed representing thousands of bug fixes, editorial fixes
| and other improvements. Additionally, numerous software tools were
| developed to aid in this effort including Ecmarkup, Ecmarkdown, and
| Grammarkdown. This specification also includes support for a new
| exponentiation operator and adds a new method to Array.prototype called
| includes.
>> > I would rather defer to Array.from, but yes, if I wanted to
>> > micro-optize:
>> >
>> > var filter = (xs,fn) => Array.prototype.filter.call(xs,fn)
>>
>> [For example, I found the advantage of that syntax over
>>
>> var filter = function (xs, fn) {
>> return Array.prototype.filter.call(xs, fn);
>> }
>>
>> to be negligibly small. The latter is even clearer than the former: I
>> do not have to look closely to know that .filter() is not .call()ed
>> before the anonymous function is called.]
>
> If you dislike it as being too terse, fair enough. I assume you know that
> the semantics of "function(){...this...}" differ from "() => {...this...}"
No, I was unaware that “this” would be the “undefined” value with the arrow
function syntax with braces when the defined function is called. I find it
even more disturbing that “arguments” is not defined with either arrow
function syntax. (Tested in the Chrome DevTools console in Chromium
“51.0.2704.79 Built on 8.4, running on Debian stretch/sid (64-bit)”.)
>> In any case, this is not a good idea because it requires resolution of
>> “Array.prototype.filter” along the scope chain every time the filter
>> function is called. It is not micro-optimization, but *de*optimization.
>
> Assuming the Tracing JIT doesn't do its job... [1]
That argument is based on wishful thinking. There does not have to be a
Tracing JIT in the first place.
>> […] Language binding was specified [in DOM Level 2 and 3 Core] so that
>> in certain programming languages features of the DOM were easier to use.
>> For example, if “list” refers to an object implementing the NodeList
>> interface, you can write “list[1]” instead of “list.item(1)” in
>> ECMAScript implementations because the language binding section of the
>> DOM Specification says so.
>> […]
>> The aforementioned simplification is no longer specified by language
>> binding in DOM4 but simply as alternative syntax (with no reference to
>> “JavaScript” whatsoever). (From this we can assume that inheritance
>> from Array.prototype was not possible if the DOM was to be kept
>> language-indepent.)
>
> JavaScript isn't expressive enough (Yet?) to define the constraints and
> intent properly anyway. (interfaces and such)
That depends on what you call “JavaScript”. But from ECMAScript Edition 3
on you can certainly implement interfaces in all ways that matter:
- You can define an interface as an object (of a user-defined type) that has
certain no-op methods;
- You can define that a user-defined type implements an interface, meaning
that its prototype must implement the methods of the interface that
the type implements;
- you can subject an object to an interface test (it must inherit or
implement certain methods) and throw an exception if it does not pass
that test.
It is possible to improve on that by defining an interface as an object that
(additionally) has a description of required properties and property types
as as properties, and work with that in the same way. One can define
setters and getters so that the initial type of a property is preserved, or
one can use language extensions (e.g. for strict typing).
> Frankly, after 20 some odd years of me living/developing in this web
> world, I don't care too much anymore about the evolution of these standard
> bodies. The passion is gone and there's nothing new under the sun AFAIC.
> No more archaeology, and no more bazaars as far as I can manage. The
> cathedral is where I trek. [2][3]
That may be so, but you are missing the point: the problem is not with the
standards bodies but intrinsic in the relevant, evolutionally grown APIs.
It can only be solved satisfactorily by foregoing all attempts at
compatibility (backwards *and* forwards), and that would be unwise at best.
Please trim your quotes from now on. Also, you should not repeat the
attribution lines in each section.
--
PointedEars
FAQ: <http://PointedEars.de/faq> | SVN: <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | ES Matrix: <http://PointedEars.de/es-matrix>
Please do not cc me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | "Michael Haufe (TNO)" <tno@thenewobjective.com> |
|---|---|
| Date | 2016-08-15 23:16 -0700 |
| Message-ID | <165cb2e8-dca2-495f-80d9-4c17d90cba2f@googlegroups.com> |
| In reply to | #31110 |
Thomas 'PointedEars' Lahn wrote:
> Michael Haufe (TNO) wrote:
> > "just for the sake of it"? I think there is something behind this you
> > could expand on.
>
> Because it’s “cool” to use it, not because there is considerable *tangible*
> benefit in using it.
I think I see where you're coming from.
CoffeeScript vs. Babel for instance.
The former being a cutesy short syntax and fundamentally broken semantically
The latter for it's downrev compilation.
> > I'd rather people kept with "compiler".
>
> There is a difference. “Transpiler” is in fact a not-so-new [1] portmanteau
> standing for “transcoding compiler” which in turn stands in for “translating
> source-to-source compiler”. The difference is that a compiler usually does
> not generate source code, but *machine* code.
>
> <https://en.wikipedia.org/wiki/Source-to-source_compiler>
>
> [1]
> <https://www.google.com/search?q=transpiler&safe=active&source=lnt&tbs=cdr%3A1%2Ccd_min%3A01.01.1960%2Ccd_max%3A31.12.2000&tbm=>
>
> (The Google Books Ngram Viewer at <https://books.google.com/ngrams> did not
> have “transpiler”, so I tried a time-based Google Search.)
Right, but it's the vagueness I find somewhat irksome. 100% opinion based.
> > Which of these counts as "transpilation" vs. "compilation"?
> >
> > ES6 -> ES6 (minified)
>
> That does not count either as transpilation or compilation in my book
> because the underlying programming language stays the same. Therefore the
> proper term is, obviously, “minification” or “minifying”, which I would
> categorize as a form of automated refactoring, and define as refactoring in
> order to generate equivalent source code that is as small as possible.
Right. The semantics are the same.
> > ES6 -> ES5
> > ES6 -> ES3
>
> It is debatable whether that alone can be called transpilation because one
> could argue that the underlying programming language stays the same
> (ECMAScript), only that the resulting source code is executable by an
> implementation of an earlier specification of it. However, usually the
> software that does this conversion does more than just that (I am thinking
> of the TypeScript compiler as an example).
You see this debate in other languages as well.
Perl 6 vs Perl 5.
Python 2 vs Python 3
While the differening versions still have the same name,
they're semantically different as well as syntactically.
> > ES6 -> asm.js
>
> Is there such a thing? If yes, see above, as asm.js is “an extraordinarily
> optimizable, low-level subset of JavaScript”, according to its Web site, and
> “a strict subset of JavaScript” according to its Specification (August
> 2014[!] Working Draft).
I'm still using the legacy terminology. It's been succeeded by WebAssembly which is on a standards track:
<https://webassembly.github.io/>
> BTW, I recently noticed that the 7th Edition of the ECMAScript Language
> Specification, ECMAScript 2016, has been published in 2016-06. The HTML
> version is available at <http://ecma-international.org/ecma-262/7.0/>.
> It should be noted that
>
> | [that] ECMAScript specification is the first ECMAScript edition released
> | under Ecma TC39's new yearly release cadence and open development process.
> | A plain-text source document was built from the ECMAScript 2015 source
> | document to serve as the base for further development entirely on GitHub.
> | Over the year of this standard's development, hundreds of pull requests
> | and issues were filed representing thousands of bug fixes, editorial fixes
> | and other improvements. Additionally, numerous software tools were
> | developed to aid in this effort including Ecmarkup, Ecmarkdown, and
> | Grammarkdown. This specification also includes support for a new
> | exponentiation operator and adds a new method to Array.prototype called
> | includes.
Yes, I'm still subscribed to es-discuss mailing list and contribute once in a blue moon.
> > If you dislike it as being too terse, fair enough. I assume you know that
> > the semantics of "function(){...this...}" differ from "() => {...this...}"
>
> No, I was unaware that “this” would be the “undefined” value with the arrow
> function syntax with braces when the defined function is called. I find it
> even more disturbing that “arguments” is not defined with either arrow
> function syntax. (Tested in the Chrome DevTools console in Chromium
> “51.0.2704.79 Built on 8.4, running on Debian stretch/sid (64-bit)”.)
regarding "arguments", that's what rest parameters are for now:
<https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters>
regarding "this", you can some of the semantics:
//ES6
var foo = {
m1: function(){ this },
m2: () => this,
m3(){ return this }
}
//ES5
var _this = this;
var foo = {
m1: function () { this; },
m2: function () { return _this; },
m3: function () { return this; }
};
This is more useful when used with a class:
//ES6
class Foo {
method(){
var self = this;
var foo = {
m1: function(){ this },
m2: () => this,
m3(){ return this }
}
}
}
//ES5
function Foo() {}
Foo.prototype.method = function(){
var _this = this;
var self = this;
var foo = {
m1: function () { this; },
m2: function () { return _this; },
m3: function () { return this; }
};
};
> > Assuming the Tracing JIT doesn't do its job... [1]
>
> That argument is based on wishful thinking. There does not have to be a
> Tracing JIT in the first place.
My point here was that this should be a very low priority during development.
I don't want to see too much cleverness in code for the sake of minor perf-gains
The worst example here is manual loop unrolling, which used to be a fad in ES3 days:
<https://en.wikipedia.org/wiki/Loop_unrolling#Static.2Fmanual_loop_unrolling>
> > JavaScript isn't expressive enough (Yet?) to define the constraints and
> > intent properly anyway. (interfaces and such)
>
> That depends on what you call “JavaScript”. But from ECMAScript Edition 3
> on you can certainly implement interfaces in all ways that matter:
>
> - You can define an interface as an object (of a user-defined type) that has
> certain no-op methods;
>
> - You can define that a user-defined type implements an interface, meaning
> that its prototype must implement the methods of the interface that
> the type implements;
>
> - you can subject an object to an interface test (it must inherit or
> implement certain methods) and throw an exception if it does not pass
> that test.
>
> It is possible to improve on that by defining an interface as an object that
> (additionally) has a description of required properties and property types
> as as properties, and work with that in the same way. One can define
> setters and getters so that the initial type of a property is preserved, or
> one can use language extensions (e.g. for strict typing).
That's implying the constraints and semantics more than declaring them.
I fall on the side of the type debate that says that typed languages
are more expressive than untyped ones (Church Typing over Curry Typing).
We could debate this, but we'll be repeating some very detailed
arguments from Lambda The Ultimate. About once a year I revisit this
very long thread. It's worth wading through if you have the patience
and any interest in Programming Language Theory:
<http://lambda-the-ultimate.org/node/100>
<http://lambda-the-ultimate.org/node/175>
<http://lambda-the-ultimate.org/node/220>
(warning): VERY long read. A vague summary on the part we're touching one:
<http://www.lispcast.com/church-vs-curry-types>
> That may be so, but you are missing the point: the problem is not with the
> standards bodies but intrinsic in the relevant, evolutionally grown APIs.
> It can only be solved satisfactorily by foregoing all attempts at
> compatibility (backwards *and* forwards), and that would be unwise at best.
Oh I know the point all too well, having been burned by the XHTML2 movement.
I'm moreso expressing frustration with the sort of things we've both seen
over the years, such as your example of jQuery perverting standards, and
ASCII-turd CSS attempts: <https://www.w3.org/TR/css3-layout/>
I'm all for standards and evolution over revolution, but it continues to
be a sad state of affairs IMO that there is such a lack of perspective
and/or experience from so many on these committees...
[toc] | [prev] | [next] | [standalone]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2016-08-06 10:28 +0200 |
| Message-ID | <XnsA65C6A9E0A1C7eejj99@194.109.6.166> |
| In reply to | #31082 |
Andrew Poulos <ap_prog@hotmail.com> wrote on 06 Aug 2016 in
comp.lang.javascript:
> I have a number of DIV elements many of which start with the ID
> "clickable_" and end with either an integer or some alphabetic characters.
>
> I need to only select those that end with an integer. I can get the ones
> that start with "clickable_" using
>
> var clickables = document.querySelectorAll('[id^="clickable_"]');
>
> but when I try to filter it further I get stuck.
>
> var clickables = document.querySelectorAll('[id^="clickable_"]').filter(
> function() {
> return this.id.match(/_\d*$/);
>});
>
> gives me ...filter is not a function.
>
> How can I get just the elements whose ID that starts with "clickable_"
> and ends with an integer?
Use (let ... of ..),
so you don't have to convert DOM-collections to Javascript-arrays first,
then use regex test().
===================
'use strict'
window.onload = function() {
let clickables = document.querySelectorAll('[id^="clickable_"]');
for (let clk of clickables )
if ( /\d$/.test(clk.id) )
clk.innerHTML += ' yes!'; // or whatever you want to do
};
====================
--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.javascript
csiph-web