Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #20180 > unrolled thread

Alignment of three tables

Started by"Mel Smith" <med_cutout_syntel@aol.com>
First post2013-06-09 08:49 -0600
Last post2013-06-12 18:56 +0100
Articles 20 on this page of 24 — 10 participants

Back to article view | Back to comp.lang.javascript


Contents

  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 →


#20180 — Alignment of three tables

From"Mel Smith" <med_cutout_syntel@aol.com>
Date2013-06-09 08:49 -0600
SubjectAlignment 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]


#20181

FromScott Sauyet <scott.sauyet@gmail.com>
Date2013-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]


#20182

FromDenis McMahon <denismfmcmahon@gmail.com>
Date2013-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]


#20183

From"Mel Smith" <med_cutout_syntel@aol.com>
Date2013-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]


#20186

FromDenis McMahon <denismfmcmahon@gmail.com>
Date2013-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]


#20185

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-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]


#20190

FromJohn Harris <niam@jghnorth.org.uk.invalid>
Date2013-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]


#20192

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-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]


#20191

From"Mel Smith" <med_cutout_syntel@aol.com>
Date2013-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]


#20193

From"Mel Smith" <med_cutout_syntel@aol.com>
Date2013-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]


#20196

FromDenis McMahon <denismfmcmahon@gmail.com>
Date2013-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]


#20197

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-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]


#20206

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2013-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]


#20208

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-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]


#20291

FromStefan Weiss <krewecherl@gmail.com>
Date2013-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]


#20293

FromEric Bednarz <bednarz@fahr-zur-hoelle.org>
Date2013-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]


#20294

FromStefan Weiss <krewecherl@gmail.com>
Date2013-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]


#20295

FromEric Bednarz <bednarz@fahr-zur-hoelle.org>
Date2013-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]


#20301

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-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]


#20300

FromThomas 'PointedEars' Lahn <PointedEars@web.de>
Date2013-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