Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.javascript > #20180 > unrolled thread
| Started by | "Mel Smith" <med_cutout_syntel@aol.com> |
|---|---|
| First post | 2013-06-09 08:49 -0600 |
| Last post | 2013-06-12 18:56 +0100 |
| Articles | 20 on this page of 24 — 10 participants |
Back to article view | Back to comp.lang.javascript
Alignment of three tables "Mel Smith" <med_cutout_syntel@aol.com> - 2013-06-09 08:49 -0600
Re: Alignment of three tables Scott Sauyet <scott.sauyet@gmail.com> - 2013-06-09 08:18 -0700
Re: Alignment of three tables Denis McMahon <denismfmcmahon@gmail.com> - 2013-06-09 20:02 +0000
Re: Alignment of three tables "Mel Smith" <med_cutout_syntel@aol.com> - 2013-06-09 15:01 -0600
Re: Alignment of three tables Denis McMahon <denismfmcmahon@gmail.com> - 2013-06-09 22:50 +0000
Re: Alignment of three tables Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-10 00:46 +0200
Re: Alignment of three tables John Harris <niam@jghnorth.org.uk.invalid> - 2013-06-10 14:41 +0100
Re: Alignment of three tables Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-10 17:35 +0200
Re: Alignment of three tables "Mel Smith" <med_cutout_syntel@aol.com> - 2013-06-10 09:08 -0600
Re: Alignment of three tables "Mel Smith" <med_cutout_syntel@aol.com> - 2013-06-10 11:16 -0600
Re: Alignment of three tables Denis McMahon <denismfmcmahon@gmail.com> - 2013-06-11 02:05 +0000
Re: Alignment of three tables Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-11 05:09 +0200
Re: Alignment of three tables "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2013-06-11 10:59 +0200
Re: Alignment of three tables Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-11 16:51 +0200
Re: Alignment of three tables Stefan Weiss <krewecherl@gmail.com> - 2013-06-14 15:38 +0200
Re: Alignment of three tables Eric Bednarz <bednarz@fahr-zur-hoelle.org> - 2013-06-14 20:26 +0200
Re: Alignment of three tables Stefan Weiss <krewecherl@gmail.com> - 2013-06-14 21:22 +0200
Re: Alignment of three tables Eric Bednarz <bednarz@fahr-zur-hoelle.org> - 2013-06-15 00:36 +0200
Re: Alignment of three tables Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-15 12:04 +0200
Re: Alignment of three tables Thomas 'PointedEars' Lahn <PointedEars@web.de> - 2013-06-15 11:41 +0200
Re: Alignment of three tables Stefan Weiss <krewecherl@gmail.com> - 2013-06-15 13:53 +0200
Re: Alignment of three tables Scott Sauyet <scott.sauyet@gmail.com> - 2013-06-17 04:28 -0700
Re: Alignment of three tables "Andy" <andy@NOSPAMmanyplay.com> - 2013-06-10 09:19 +0100
Re: Alignment of three tables Dr J R Stockton <reply1300@merlyn.demon.co.uk.invalid> - 2013-06-12 18:56 +0100
Page 1 of 2 [1] 2 Next page →
| From | "Mel Smith" <med_cutout_syntel@aol.com> |
|---|---|
| Date | 2013-06-09 08:49 -0600 |
| Subject | Alignment of three tables |
| Message-ID | <b1jivmF20mgU1@mid.individual.net> |
Hi:
I have three tables in a <div> placed on the right-half of the screen.
These tables are placed one beneath the other, and have the same number
of columns <td>. I want the columns of all three tables to be lined up
vertically.
What is the best technique please ?
Thanks,
--
Mel Smith
[toc] | [next] | [standalone]
| From | Scott Sauyet <scott.sauyet@gmail.com> |
|---|---|
| Date | 2013-06-09 08:18 -0700 |
| Message-ID | <2f67b89f-c4b3-40dc-a67c-73ed846383c8@m13g2000vbo.googlegroups.com> |
| In reply to | #20180 |
Mel Smith wrote: > I have three tables in a <div> placed on the right-half of the screen. > > These tables are placed one beneath the other, and have the same number > of columns <td>. I want the columns of all three tables to be lined up > vertically. > > What is the best technique please ? This sounds like it belongs in another group. Try a markup, web authoring, or CSS-focused group. -- Scott
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2013-06-09 20:02 +0000 |
| Message-ID | <kp2n16$ror$1@dont-email.me> |
| In reply to | #20180 |
On Sun, 09 Jun 2013 08:49:24 -0600, Mel Smith wrote: > What is the best technique please ? The problem seems to be that your table and column widths may not match across the three tables. The following untested javascript attempts to set 3 tables each with 7 columns so that all columns in each table have the same width. Note that it even if it works on plain tables, it will break if any of the tables has, for example, a cell containing a rowspan or colspan attribute with a value other than 1. Consider a table with two similar sets of 3 columns either side of a spacer column, the 3 main column widths are 95, 150 and 150 px, the spacer column is 10 px, and the table width is 800 px: cwidths = new Array( 95, 150, 150, 10, 95, 150, 150 ); tables = document.getElementsByTagName( "table" ); for ( i = 0; i < tables.length; i++ ) for ( j = 0; j < tables[i].rows.length; j++ ) for ( k = 0; k < tables[i].rows[j].length; k++ ) tables[i].rows[j].cells[k].style.width = cwidths[k]; This may not be the best technique. Pointy will probably decry it as being utter crap, without actually offering any viable alternative, because that's what pointy usually does. Technically it's possible that you should refer to the elements in each collection of nodes using "collection.item(index)" instead of "collection [index]", so that then the three references: tables[i].rows.length tables[i].rows[j].length tables[i].rows[j].cells[k].style.width would become something like: tables.item(i).rows.length tables.item(i).rows.item(j).length tables.item(i).rows.item(j).cells.item(k).style.width etc etc, but in practice, I believe that both methods work equally well. It may be faster to simply process row 0 of each table, as long as nothing will have attempted to set the widths of any other cells: cwidths = new Array( 95, 150, 150, 10, 95, 150, 150 ); tables = document.getElementsByTagName( "table" ); for ( i = 0; i < tables.length; i++ ) for ( k = 0; k < tables[i].rows[0].length; k++ ) tables[i].rows[0].cells[k].style.width = cwidths[k]; -- Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | "Mel Smith" <med_cutout_syntel@aol.com> |
|---|---|
| Date | 2013-06-09 15:01 -0600 |
| Message-ID | <b1k8pnF6s3gU1@mid.individual.net> |
| In reply to | #20182 |
Denis said:
> The problem seems to be that your table and column widths may not match
> across the three tables. The following untested javascript attempts to
> set 3 tables each with 7 columns so that all columns in each table have
> the same width.
>
I *try to make them match with <td width="nn%" > in each of the
vertical columns -- where nn is the same in a column for each of the three
tables.
My ''nn' values add up to 97% for eachch of the tables. The middle table
may/may not have an overflow which brings the sliders into play. too
> Note that it even if it works on plain tables, it will break if any of
> the tables has, for example, a cell containing a rowspan or colspan
> attribute with a value other than 1.
>
There are no colspans or row spans
> Consider a table with two similar sets of 3 columns either side of a
> spacer column, the 3 main column widths are 95, 150 and 150 px, the
> spacer column is 10 px, and the table width is 800 px:
>
> cwidths = new Array( 95, 150, 150, 10, 95, 150, 150 );
>
> tables = document.getElementsByTagName( "table" );
> for ( i = 0; i < tables.length; i++ )
> for ( j = 0; j < tables[i].rows.length; j++ )
> for ( k = 0; k < tables[i].rows[j].length; k++ )
> tables[i].rows[j].cells[k].style.width = cwidths[k];
>
> This may not be the best technique. Pointy will probably decry it as
> being utter crap, without actually offering any viable alternative,
> because that's what pointy usually does.
>
> Technically it's possible that you should refer to the elements in each
> collection of nodes using "collection.item(index)" instead of "collection
> [index]", so that then the three references:
>
> tables[i].rows.length
> tables[i].rows[j].length
> tables[i].rows[j].cells[k].style.width
>
> would become something like:
>
> tables.item(i).rows.length
> tables.item(i).rows.item(j).length
> tables.item(i).rows.item(j).cells.item(k).style.width
>
> etc etc, but in practice, I believe that both methods work equally well.
>
> It may be faster to simply process row 0 of each table, as long as
> nothing will have attempted to set the widths of any other cells:
>
> cwidths = new Array( 95, 150, 150, 10, 95, 150, 150 );
>
> tables = document.getElementsByTagName( "table" );
> for ( i = 0; i < tables.length; i++ )
> for ( k = 0; k < tables[i].rows[0].length; k++ )
> tables[i].rows[0].cells[k].style.width = cwidths[k];
Hi Denis:
I'll review your js above and see what I can accomplish
Thank you !
-Mel
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2013-06-09 22:50 +0000 |
| Message-ID | <kp30rt$ror$3@dont-email.me> |
| In reply to | #20183 |
On Sun, 09 Jun 2013 15:01:39 -0600, Mel Smith wrote: > Hi Denis: > > I'll review your js above and see what I can accomplish > > Thank you ! Yeah - note that I noticed an error in it: this item: tables[i].rows[j].length should be: tables[i].rows[j].cells.length (i.e. the length of the cells collection in row j of table i) likewise this item: tables.item(i).rows.item(j).length should be: tables.item(i).rows.item(j).cells.length (i.e. the length of the cells collection in item j of the rows collection of item i of the tables collection) -- Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-06-10 00:46 +0200 |
| Message-ID | <9415734.fqrm2ecmqt@PointedEars.de> |
| In reply to | #20182 |
Denis McMahon wrote:
> On Sun, 09 Jun 2013 08:49:24 -0600, Mel Smith wrote:
>> What is the best technique please ?
>
> The problem seems to be that your table and column widths may not match
> across the three tables. The following untested javascript attempts to
> set 3 tables each with 7 columns so that all columns in each table have
> the same width.
>
> Note that it even if it works on plain tables, it will break if any of
> the tables has, for example, a cell containing a rowspan or colspan
> attribute with a value other than 1.
>
> Consider a table with two similar sets of 3 columns either side of a
> spacer column, the 3 main column widths are 95, 150 and 150 px, the
> spacer column is 10 px, and the table width is 800 px:
>
> cwidths = new Array( 95, 150, 150, 10, 95, 150, 150 );
^^^^^^^ ^^^^^^^^^
[1]
> tables = document.getElementsByTagName( "table" );
^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^[3]
[1]
> for ( i = 0; i < tables.length; i++ )
^[1] ^^^^^^^^^^^^^ ^^^[5]
[3, 4]
> for ( j = 0; j < tables[i].rows.length; j++ )
^[1] ^^^^^^^^^^^^^^^^^^^^^ ^^^[5]
[4]
> for ( k = 0; k < tables[i].rows[j].length; k++ )
^[2] ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^[5]
[4]
> tables[i].rows[j].cells[k].style.width = cwidths[k];
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^[6]
[4]
[1] Undeclared identifier (jslint: “implied global variable”)
[2] Use of error-prone Array constructor instead of safe Array initialiser
[3] Unchecked property access
[4] Inefficient, unnecessary repeated property access
[5] Inefficient increment
[6] Missing CSS unit of length, only effective in Quirks/Compatibility Mode.
See below for the considerably improved version.
> This may not be the best technique.
It is not. It is not even the third-best technique.
> Pointy will probably decry it as being utter crap,
I have never used the c-word before and I will not start using it now.
> without actually offering any viable alternative,
Plain CSS provides several viable alternatives already:
/* CSS1 */
col.col1, th, td.col1 {
width: 95px;
}
/* CSS2 */
col:first-child, td:first-child {
width: 95px;
}
/* CSS1 */
col.col2, td.col2 {
width: 150px;
}
/* CSS3 */
col::nth-child(2), td::nth-child(2) {
width: 150px;
}
/* … */
Or in ECMAScript/DOM, if the third-best technique must be used:
var widths = [95, 150, 150, 10, 95, 150, 150];
var tables = document.getElementsByTagName("table");
for (var i = 0,
len = tables && tables.length;
i < len;
++i)
{
for (var j = 0,
cells = tables[i].rows[0].cells,
len2 = cells.length;
j < len2;
++j)
{
cells[j].style.width = cwidths[k] + "px";
}
}
A table column is in general always as wide as the widest cell of the
column. Defining the CSS-width of the cells of other rows than the first
row (of a table body), too, has *no* (positive) effect.
> because that's what pointy usually does.
You should probably see someone about your unjustified overconfidence, and
about your fixation on the person you call “pointy”.
> Technically it's possible that you should refer to the elements in each
> collection of nodes using "collection.item(index)" instead of "collection
> [index]", so that then the three references:
>
> tables[i].rows.length
> tables[i].rows[j].length
> tables[i].rows[j].cells[k].style.width
>
> would become something like:
>
> tables.item(i).rows.length
> tables.item(i).rows.item(j).length
> tables.item(i).rows.item(j).cells.item(k).style.width
>
> etc etc, but in practice, I believe that both methods work equally well.
Again your belief is not supported by fact, let alone a rational thinking
and reasoning process.
It is neither necessary nor recommended to call the item(…) method on those
_NodeLists_ (or the namedItem() method on HTMLCollections). The bracket
property accessor syntax suffices and is the best current practice.
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | John Harris <niam@jghnorth.org.uk.invalid> |
|---|---|
| Date | 2013-06-10 14:41 +0100 |
| Message-ID | <aplbr8dvj9bar85a8ji8qqmm7dsn40repk@4ax.com> |
| In reply to | #20185 |
On Mon, 10 Jun 2013 00:46:48 +0200, Thomas 'PointedEars' Lahn
<PointedEars@web.de> wrote:
<snip>
>Plain CSS provides several viable alternatives already:
>
> /* CSS1 */
> col.col1, th, td.col1 {
> width: 95px;
> }
<snip>
Since when have px values been a good idea outside of image
dimensions?
John
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-06-10 17:35 +0200 |
| Message-ID | <2543512.lz8g3PJo6X@PointedEars.de> |
| In reply to | #20190 |
John Harris wrote:
> Thomas 'PointedEars' Lahn wrote:
> <snip>
>> Plain CSS provides several viable alternatives already:
>>
>> /* CSS1 */
>> col.col1, th, td.col1 {
>> width: 95px;
>> }
> <snip>
>
> Since when have px values been a good idea outside of image
> dimensions?
They are not. If you read more carefully, I have provided the plain-CSS
equivalents of Denis’ script when it were executed in Quirks Mode; that
script is a bad example in that regard as well. This approach works with
any CSS unit of length.
I would use “em” or “%”, depending on whether it mattered more that the text
content fits well into the column or that the column widths were
proportional to the width of the containing block, respectively. And I
would use “(min-)width” and “max-width” on “th” and “td” elements if the
actual column width should not be changed by cell content, with the
mentioned “overflow” etc.
It should also be noted that attribute selectors would rather easily allow
to consider cells that span several columns in CSS, although for older
layout engines you would have to use yet another CSS class (several CSS
classes can be specified for the same element).
<http://caniuse.com/#feat=css-sel2>
F'up2 comp.infosystems.www.authoring.stylesheets
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | "Mel Smith" <med_cutout_syntel@aol.com> |
|---|---|
| Date | 2013-06-10 09:08 -0600 |
| Message-ID | <b1m8g6Fjnc5U1@mid.individual.net> |
| In reply to | #20185 |
Denis and Thomas said:
> snip <
> Or in ECMAScript/DOM, if the third-best technique must be used:
>
> var widths = [95, 150, 150, 10, 95, 150, 150];
> var tables = document.getElementsByTagName("table");
> for (var i = 0,
> len = tables && tables.length;
> i < len;
> ++i)
> {
> for (var j = 0,
> cells = tables[i].rows[0].cells,
> len2 = cells.length;
> j < len2;
> ++j)
> {
> cells[j].style.width = cwidths[k] + "px";
> }
> }
>
> A table column is in general always as wide as the widest cell of the
> column. Defining the CSS-width of the cells of other rows than the first
> row (of a table body), too, has *no* (positive) effect.
>
Hi Thomas & Denis:
Thank you both for your suggestions.
(To my clients, the three tables look like *one* table with an
always-visible top row, and an always visible bottom row, and up to 1500
data rows between them)
I will re-build my three tables acccoding to the 'third-best' technique
(because I understand it better), and strip out all the 'width' stuff from
the <table> definitions and place it in my JavaScript.
However, I am now trying to remove as much of the 'px' stuff as I can,
and replace most sizing with 'em' and '%' definitions.
My three 'tables' are :
- A top table of one <thead> section with one <tr> row *only* (of
five <th> columns). This 'table' serves as an *always-visible* caption-like
row for the middle table. I do not use the <caption> tag because it
disapears on scrolling the middle table
- A middle table of data of data with up to nearly 1500 rows (of
five columns) containing all the data, and finishing with a <tfoot> section
of one <tr> row with five <th> columns . This table always has a scroll-bar
on the right-side to traverse the (up to) 1500 rows
- A bottom table of one <thead> section with one <tr> row, and
five <th> columns. Two of the <th> columns serve as searh <input> text
fields. This table serves as the always-visible means of quickly searching
for values in the main table above it.
So, I'll try to remove all my width stuff from the tables, and place
them in an onload JS function. Because I'm building for the DocType HTML5
now, I want to replace a lot of my 'px' sizing with 'em' or '%' -- as I
mentioned above.
Thanks again.
-Mel
I
[toc] | [prev] | [next] | [standalone]
| From | "Mel Smith" <med_cutout_syntel@aol.com> |
|---|---|
| Date | 2013-06-10 11:16 -0600 |
| Message-ID | <b1mfv8Flc2aU1@mid.individual.net> |
| In reply to | #20191 |
To Thomas and Denis:
Here is my js code below for sizing three of my five tables on my page. It
works and looks great and thank you !
When viewing on a wide screen, I notice a very slight mis-alignment that
I can probably cure with non-integer percentages (e.g., 6.4% )
But for now, thanks again to you both !
-Mel Smith
**********************************************
function setcolwidths () {
var i,j,pwidths,tables,cells,len,len2 ;
pwidths = [10, 44, 23, 6, 16]; // width of columns in percentages -- 99%
total
tables = [getobj("ifixedheader"),getobj("icrstable"),getobj("ifixedfooter")]
for (i= 0,len = tables && tables.length;i < len;++i) {
for (j=0,cells = tables[i].rows[0].cells,len2 = cells.length;j <
len2;++j) {
cells[j].style.width = pwidths[j] + "%";
}
}
}
[toc] | [prev] | [next] | [standalone]
| From | Denis McMahon <denismfmcmahon@gmail.com> |
|---|---|
| Date | 2013-06-11 02:05 +0000 |
| Message-ID | <kp60kh$nrp$1@dont-email.me> |
| In reply to | #20193 |
On Mon, 10 Jun 2013 11:16:19 -0600, Mel Smith wrote: Hi Mel Given: > pwidths = [10, 44, 23, 6, 16]; and: > cells[j].style.width = pwidths[j] + "%"; You're adding a number to a string. When you try and add disparate types, the type to the right side of the + is usually coerced to the type to the left side of the +, if possible - and if it's not possible either some sort of error occurs or some unexpected result may be generated. It might be safer to either store the pwidths as strings: pwidths = ["10", "44", "23", "6", "16"]; or use: cells[j].style.width = "" + pwidths[j] + "%"; In the latter, addition with an empty string on the left of the + will coerce the number on the right to a string as it applies the addition left to right, and then add that string to the "%". -- Denis McMahon, denismfmcmahon@gmail.com
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-06-11 05:09 +0200 |
| Message-ID | <2068082.pen2y8QiGc@PointedEars.de> |
| In reply to | #20196 |
Denis McMahon wrote: > On Mon, 10 Jun 2013 11:16:19 -0600, Mel Smith wrote: > > Given: > >> pwidths = [10, 44, 23, 6, 16]; > > and: > >> cells[j].style.width = pwidths[j] + "%"; > > You're adding a number to a string. No, they are correctly *concatenating* a primitive Number value and a primitive String value, which causes the former to be converted to String. > When you try and add disparate types, the type to the right side of the + > is usually coerced to the type to the left side of the +, if possible - > and if it's not possible either some sort of error occurs or some > unexpected result may be generated. Utter nonsense. Conversion to String (which happens when either operand is of type String) is *always* possible unless an object to be converted neither has nor inherits a toString() or valueOf() method. There is *never* an error (exception) on type conversion of values of primitive types because those values are converted to corresponding object values (wrapper objects) who always have or inherit both those methods. Whether the result of the implicit type conversion is useful, and whether assigning the result to a property throws an exception is another matter. However, *this* result *is* useful and the expression does *not* throw an exception. In fact, the “width” property of “style” objects is specified and implemented to accept *only* (DOM)String values, so that when you assign a plain Number value it is likely converted to a String value (having no effect except in Quirks Mode or when the number is 0). <http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSS2Properties> > It might be safer to either store the pwidths as strings: It would *definitely* be safer for everyone if you stopped posting until you RTFM, RTFSpec, and got a minimum clue, as all you can post now are your fantasies about how the languages and APIs would be – utter nonsense. > […] > or use: > > cells[j].style.width = "" + pwidths[j] + "%"; OMG. > In the latter, addition with an empty string on the left of the + will > coerce the number on the right to a string as it applies the addition > left to right, and then add that string to the "%". The algorithm for “+” makes it unnecessary to concatenate "" here; there is no preference in the algorithm towards left-to-right conversion. So it suffices that *either* operand is of type String for concatenation *instead of* addition to occur: <http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1> That either order works is frequently a problem with beginners when they attempt to add a Number value to the value of an “input” element, whereas the latter is specified and implemented as a (DOM)String value: <http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-49531485> <http://www.w3.org/TR/2012/CR-html5-20121217/forms.html#the-input-element> (There are several ways how to convert a String to a Number, all explained in the FAQ.) -- PointedEars Twitter: @PointedEars2 Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | "Evertjan." <exxjxw.hannivoort@inter.nl.net> |
|---|---|
| Date | 2013-06-11 10:59 +0200 |
| Message-ID | <XnsA1DC6FC427B06eejj99@194.109.133.133> |
| In reply to | #20197 |
Thomas 'PointedEars' Lahn wrote on 11 jun 2013 in comp.lang.javascript:
>> cells[j].style.width = "" + pwidths[j] + "%";
> The algorithm for + makes it unnecessary to concatenate "" here;
'here' indeed.
> there is no preference in the algorithm towards left-to-right
> conversion.
not quite correct, Thomas, there is a strong preference:
<script type='text/javascript'>
function f(x) {
document.write( x + '<br>' + typeof x + '<br><br>' );
};
f( 4 + 4 + '5' ); // 85
f( 4 + 4 + '' + 5 ); // 85
f( '4' + 4 + 5 ); // 455
f( '' + 4 + 4 + 5 ); // 455
f( 4 + (4 + 5) + '' ); // 13
f( '' + 4 + (4 + 5) ); // 49
f( 4 + '' + (4 + 5) ); // 49
</script>
--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-06-11 16:51 +0200 |
| Message-ID | <3002636.TxiHlyYqki@PointedEars.de> |
| In reply to | #20206 |
Evertjan. wrote:
> Thomas 'PointedEars' Lahn wrote on 11 jun 2013 in comp.lang.javascript:
>>> cells[j].style.width = "" + pwidths[j] + "%";
>> The algorithm for + makes it unnecessary to concatenate "" here;
>
> 'here' indeed.
>
>> there is no preference in the algorithm towards left-to-right
>> conversion.
>
> not quite correct, Thomas, there is a strong preference:
>
> <script type='text/javascript'>
>
> function f(x) {
> document.write( x + '<br>' + typeof x + '<br><br>' );
> };
>
> f( 4 + 4 + '5' ); // 85
> […]
> f( '4' + 4 + 5 ); // 455
JFTR:
It was rather obvious that I was talking about the algorithm for the
(*binary*, as opposed to unary) “+” operator which only takes *two*
operands. I said, in essence, that because of
| 7. If Type(lprim) is String or Type(rprim) is String, then
| a. Return the String that is the result of concatenating
| ToString(lprim) followed by ToString(rprim)
*both*
4 + "5"
and
"4" + 5
result in
"45"
which is a true statement.
This has nothing to do with the left-to-right evaluation order of
expressions in these languages. The expressions in your examples
are *several* “+” operations, and because of
| The production AdditiveExpression : AdditiveExpression +
| MultiplicativeExpression is evaluated as follows:
|
| 1. Let lref be the result of evaluating AdditiveExpression.
4 + 4 + '5'
is evaluated as
(4 + 4) + "5"
leading to
8 + "5"
and therefore
"85"
Likewise,
'4' + 4 + 5
is evaluated as
("4" + 4) + 5
leading to
"44" + 5
and therefore
"445"
∎
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2013-06-14 15:38 +0200 |
| Message-ID | <kpf6dg$gpb$1@news.albasani.net> |
| In reply to | #20197 |
On 2013-06-11 05:09, Thomas 'PointedEars' Lahn wrote:
> The algorithm for “+” makes it unnecessary to concatenate "" here; there is
> no preference in the algorithm towards left-to-right conversion. So it
> suffices that *either* operand is of type String for concatenation *instead
> of* addition to occur:
>
> <http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1>
There's one thing I don't understand about that algorithm:
{} + ""
One of the operands is a string, so I would expect the result to be a
string as well, but that's not what happens: the result of this
operation is 0 in current implementations. I'm sure I misinterpreted the
algorithm somehow, but where?
- stefan
[toc] | [prev] | [next] | [standalone]
| From | Eric Bednarz <bednarz@fahr-zur-hoelle.org> |
|---|---|
| Date | 2013-06-14 20:26 +0200 |
| Message-ID | <m21u84tuoo.fsf@nntp.bednarz.nl> |
| In reply to | #20291 |
Stefan Weiss <krewecherl@gmail.com> writes:
> On 2013-06-11 05:09, Thomas 'PointedEars' Lahn wrote:
>> <http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1>
>
> There's one thing I don't understand about that algorithm:
>
> {} + ""
That's a block statement followed by an unary + operator with the empty
string as its operand.
[toc] | [prev] | [next] | [standalone]
| From | Stefan Weiss <krewecherl@gmail.com> |
|---|---|
| Date | 2013-06-14 21:22 +0200 |
| Message-ID | <kpfqho$rdb$1@news.albasani.net> |
| In reply to | #20293 |
On 2013-06-14 20:26, Eric Bednarz wrote:
> Stefan Weiss <krewecherl@gmail.com> writes:
>> There's one thing I don't understand about that algorithm:
>>
>> {} + ""
>
> That's a block statement followed by an unary + operator with the empty
> string as its operand.
*facepalm*
Of course. Thanks :)
- stefan
[toc] | [prev] | [next] | [standalone]
| From | Eric Bednarz <bednarz@fahr-zur-hoelle.org> |
|---|---|
| Date | 2013-06-15 00:36 +0200 |
| Message-ID | <m2zjuscobe.fsf@nntp.bednarz.nl> |
| In reply to | #20294 |
Stefan Weiss <krewecherl@gmail.com> writes:
> On 2013-06-14 20:26, Eric Bednarz wrote:
>> Stefan Weiss <krewecherl@gmail.com> writes:
>>> There's one thing I don't understand about that algorithm:
>>>
>>> {} + ""
>>
>> That's a block statement followed by an unary + operator with the empty
>> string as its operand.
>
> *facepalm*
>
> Of course. Thanks :)
Well, I had this terrible feeling of déjà vu. Here's the same answer
with His Master's Voice:
http://www.youtube.com/watch?feature=player_detailpage&v=Rj49rmc01Hs#t=316s
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-06-15 12:04 +0200 |
| Message-ID | <15409664.CN0A4J4lxC@PointedEars.de> |
| In reply to | #20295 |
Eric Bednarz wrote:
> Stefan Weiss <krewecherl@gmail.com> writes:
>> On 2013-06-14 20:26, Eric Bednarz wrote:
>>> Stefan Weiss <krewecherl@gmail.com> writes:
>>>> There's one thing I don't understand about that algorithm:
>>>>
>>>> {} + ""
>>>
>>> That's a block statement followed by an unary + operator with the empty
>>> string as its operand.
>>
>> *facepalm*
>>
>> Of course. Thanks :)
>
> Well, I had this terrible feeling of déjà vu.
Must be an error in the greater Matrix ;-)
> Here's the same answer with His Master's Voice:
>
>
http://www.youtube.com/watch?feature=player_detailpage&v=Rj49rmc01Hs#t=316s
YMMD (especially the Batman part). It also gave me new ideas for my Matrix.
Thank you.
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
| From | Thomas 'PointedEars' Lahn <PointedEars@web.de> |
|---|---|
| Date | 2013-06-15 11:41 +0200 |
| Message-ID | <2664592.4ckUSR1F5s@PointedEars.de> |
| In reply to | #20293 |
Eric Bednarz wrote:
> Stefan Weiss <krewecherl@gmail.com> writes:
>> On 2013-06-11 05:09, Thomas 'PointedEars' Lahn wrote:
>>> <http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1>
>>
>> There's one thing I don't understand about that algorithm:
>>
>> {} + ""
>
> That's a block statement followed by an unary + operator with the empty
> string as its operand.
Very good. I had not thought of that. To prove that ES 5.1, “11.6.1 The
Addition operator” is properly implemented as concatenation operator:
/* "[object Object]", as Stefan expected */
var x = {} + "";
or
/* "[object Object]" */
({}) + ""
or
/* "[object Object]" */
new Object() + ""
The curious – maybe not obvious – thing here is, though, that it is _not_
the "" that causes the "[object Object]" result, but the conversion of the
Object instance to a primitive value.
The ToPrimitive() algorithm (§9.1) in step 5 –
| 5. Let lprim be ToPrimitive(lval).
– calls the [[DefaultValue]] internal method, passing the PreferredType on
as argument for the hint. As there is no PreferredType, there is no hint.
Object instances are native objects. Their [[DefaultValue]] method is
specified in ECMAScript (§8.12.8). Calling it without hint works as if it
was called with hint Number. Thus, it attempts to converts its object
argument to a primitive value by attempting to call its valueOf() method
first. Object instances inherit from Object.prototype a valueOf() method
through the prototype chain; it returns a reference to the same object.
That is *not* a primitive value.
If the valueOf() method of the object cannot be called or does not return a
primitive value, [[DefaultValue]] attempts to call the object's toString()
method. Object instances inherit from Object.prototype a toString() method
through the prototype chain which always returns a primitive string value
that is the equivalent of "[object " + [[Class]] + "]" (we can use it to
tell the [[Class]] of an object, for example for Array.isArray() emulation,
as implemented by jsx.object.getClass()). Because that return value
satisfies the condition in §8.12.8, hint Number, step 4b, that is the return
value of [[DefaultValue]] and of ToPrimitive().
That in turn satisfies the condition in §11.6.1, step 7, where it says:
| 7. If Type(lprim) is String or Type(rprim) is String, then […]
It follows from logical shortcut evaluation that it does not matter that
Type("") is String, because Type(({}).toString()) already is String. As a
result, we observe in conforming implementations:
/* "[object Object]23" */
({}) + 23
And because of
| 8. Return the result of applying the addition operation to
| ToNumber(lprim) and ToNumber(rprim). See the Note below 11.6.3.
/* 42 */
({valueOf: function () { return 19; }}) + 23
[A possible application of the latter is:
function Complex (re, im)
{
/* or throw exceptions */
this.re = (re ? +re : 0)
this.im = (im ? +im : 0);
}
/**
* @overrides Object.prototype.valueOf()
*/
Complex.prototype.valueOf = function () {
if (!this.im)
{
return this.re;
}
return this;
};
/* 42 */
new Complex(19) + 23
/* 42 */
new Complex(19) + new Complex(23)
Unfortunately, without the possibility of operator overloading the following
does not work:
/* _not_ new Complex(42, 42) */
new Complex(19, 42) + new Complex(23)
But you can work around it:
Complex.prototype.add = function (o) {
/* or “Complex” if you do not care for polymorphism */
var C = this.constructor;
if (o instanceof C)
{
return new C(this.re + o.re, this.im + o.im);
}
return new C(this.re + (+o), this.im);
};
/* new Complex(42, 42) */
(new Complex(19, 42)).add(new Complex(23));
]
--
PointedEars
Twitter: @PointedEars2
Please do not Cc: me. / Bitte keine Kopien per E-Mail.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.javascript
csiph-web