Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Understanding someone's code

44 views
Skip to first unread message

Andrew Poulos

unread,
Mar 30, 2017, 12:26:40 AM3/30/17
to
I'm looking through some code I found online and one bit has this

function k() {
var a;
if (b.onScroll) b.onScroll();
b.getPageInView && (a = b.getPageInView()) && (F = a,
document.getElementById("pageNumber").value = a);
}

which has me confused. Is the line

b.getPageInView && (a = b.getPageInView()) && (F = a,
document.getElementById("pageNumber").value = a);

equivalent to

if (b.getPageInView) {
a = b.getPageInView();
F = a;
document.getElementById("pageNumber").value = a;
}

?

Andrew Poulos

Andrew Poulos

unread,
Mar 30, 2017, 3:48:46 AM3/30/17
to
Or should I have said, is equivalent to

if (b.getPageInView) {
a = b.getPageInView();
if (a) {
F = a;
document.getElementById("pageNumber").value = a;
}
}

Andrew Poulos

Evertjan.

unread,
Mar 30, 2017, 6:07:21 AM3/30/17
to
Andrew Poulos <ap_...@hotmail.com> wrote on 30 Mar 2017 in
comp.lang.javascript:
No.

The right side of && is only executed
if and after[!] execution of the left side has returned true.

So:

'use strict'
let a = 4;
document.write( a ); // 4
document.write( a && 15-15 ); // 0
document.write( a ); // 4
document.write( (a=0) && (a=1) ); // 0
document.write( a ); // 0
document.write( (a=17) && (a=0) && (a=13) ); // 0
document.write( a ); // 0


--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

Tony Mountifield

unread,
Mar 30, 2017, 7:44:01 AM3/30/17
to
In article <XnsA7487B53...@194.109.6.166>,
Why not? It looks equivalent to me, in that specific case. If you believe
it to be a wrong interpretation of the original code, why not provide
a better one, instead of the unrelated and simple example below?

> The right side of && is only executed
> if and after[!] execution of the left side has returned true.

Yes, that's right. Which is what the OP's "if" statements are doing.
Remember that in the original code, the result of the X && Y && Z
expression is discarded, not assigned.

> So:
>
> 'use strict'
> let a = 4;
> document.write( a ); // 4
> document.write( a && 15-15 ); // 0
> document.write( a ); // 4
> document.write( (a=0) && (a=1) ); // 0
> document.write( a ); // 0
> document.write( (a=17) && (a=0) && (a=13) ); // 0
> document.write( a ); // 0

All true, but not relevant to the original example.

Cheers
Tony
--
Tony Mountifield
Work: to...@softins.co.uk - http://www.softins.co.uk
Play: to...@mountifield.org - http://tony.mountifield.org

JJ

unread,
Mar 30, 2017, 7:58:15 AM3/30/17
to
On Thu, 30 Mar 2017 18:48:38 +1100, Andrew Poulos wrote:
>>
>> which has me confused. Is the line
>>
>> b.getPageInView && (a = b.getPageInView()) && (F = a,
>> document.getElementById("pageNumber").value = a);
>>
[snip]
>
> Or should I have said, is equivalent to
>
> if (b.getPageInView) {
> a = b.getPageInView();
> if (a) {
> F = a;
> document.getElementById("pageNumber").value = a;
> }
> }

Yes, it's the same.

Below code:

a=1, a=0, a=3;

Is same as below, except it's strictly for statements.

a=1; a=0; a=3;

And this part of the code:

a = b.getPageInView();
if (a) {
//...
}

Is also same as:

if (a = b.getPageInView()) {
//...
}

And you can't use code like below.

if (a=1; b=2; c=a*b) {
//...
}

You can only use it like this:

if (a=1, b=2, c=a*b) { //last expression is used for the `if` condition
//c is not NaN and is not zero
}

Evertjan.

unread,
Mar 30, 2017, 8:00:59 AM3/30/17
to
to...@mountifield.org (Tony Mountifield) wrote on 30 Mar 2017 in
comp.lang.javascript:

>> > if (b.getPageInView) {
>> > a = b.getPageInView();
>> > if (a) {
>> > F = a;
>> > document.getElementById("pageNumber").value = a;
>> > }
>> >}
>>
>> No.
>
> Why not? It looks equivalent to me, in that specific case.

Incorrect, did you test it?

After:

F = 7;
a = 0;
if (a) {
F = a;
document.getElementById("pageNumber").value = a;
}

F will be 7,

while after:

F = 7;
a = 0;
F = (F = a) && (document.getElementById("pageNumber").value = a);

F will be 0;

> If you believe
> it to be a wrong interpretation of the original code, why not provide
> a better one

This is not a church,
faith does not come into coding,
faith being nonsense anyway.

> , instead of the unrelated and simple example below?

I try to teach to the best of my knowledge,
not take over the coding,
this NG not being a helpdesk.

Tony Mountifield

unread,
Mar 30, 2017, 9:45:26 AM3/30/17
to
In article <XnsA7488E8...@194.109.6.166>,
Evertjan. <exxjxw.h...@inter.nl.net> wrote:
> to...@mountifield.org (Tony Mountifield) wrote on 30 Mar 2017 in
> comp.lang.javascript:
>
(original statement re-added for comparison)

> >> b.getPageInView && (a = b.getPageInView()) && (F = a,
> >> document.getElementById("pageNumber").value = a);

> >> > if (b.getPageInView) {
> >> > a = b.getPageInView();
> >> > if (a) {
> >> > F = a;
> >> > document.getElementById("pageNumber").value = a;
> >> > }
> >> >}
> >>
> >> No.
> >
> > Why not? It looks equivalent to me, in that specific case.
>
> Incorrect, did you test it?

It was simple enough to understand by inspection.

> After:
>
> F = 7;
> a = 0;
> if (a) {
> F = a;
> document.getElementById("pageNumber").value = a;
> }
>
> F will be 7,
>
> while after:
>
> F = 7;
> a = 0;
> F = (F = a) && (document.getElementById("pageNumber").value = a);
>
> F will be 0;

What's an initial assignment to F got to do with it? That wasn't in the
original example. Nor was your outer assignment to F in the third line.

Let's consider the original code piece by piece:

b.getPageInView && (a = b.getPageInView()) && (F = a, document.getElementById("pageNumber").value = a);

1. Evaluate b.getPageInView. If false, do nothing further due to short-
circuit evaluation, and discard its value, since it is not assigned.

2. Invoke b.getPageInView() and assign its value to a. If the assigned
value was false, do nothing further.

3. Assign the value of a to F.

4. Assign the value of a to document.getElementById("pageNumber").value

You will find exactly the same steps describe the OP's interpretation:

if (b.getPageInView) {
a = b.getPageInView();
if (a) {
F = a;
document.getElementById("pageNumber").value = a;
}
}

> > If you believe
> > it to be a wrong interpretation of the original code, why not provide
> > a better one
>
> This is not a church,
> faith does not come into coding,
> faith being nonsense anyway.

s/believe/consider/ or s/believe/think/. I was using "believe" in one of
those meanings, nothing to do with faith. Sounds like you have an axe to
grind regarding the latter.

> > , instead of the unrelated and simple example below?
>
> I try to teach to the best of my knowledge,
> not take over the coding,
> this NG not being a helpdesk.

That's true, it isn't. But if you volunteer to respond, it doesn't help
if you don't answer the question asked.

Thomas 'PointedEars' Lahn

unread,
Mar 30, 2017, 12:13:14 PM3/30/17
to
If “F” is a variable, too, then yes.

In general, no. It is a seldom-known fact that the result of an assignment
operation in ECMAScript is the value of the *right-hand side* *before*
assignment; it is _not_ the value of the left-hand side after assignment.
Therefore, the second code is only equivalent to the first one if the
assignment is successful and there is no setter to modify the assigned value
as then the left-hand side and the right-hand side of the assignment are
equal.

Counter-example:

/*
* “foo” is declared as a variable that holds a reference to an object
* with empty prototype chain (which I call a “data object”; see
* jsx.object.createDataObject(), formerly jsx.object.getDataObject()).
* The properties of that object, and their attributes, are defined
* in the following.
*/
var foo = Object.create(null, (function () {
var _bar;

return {
/*
* “bar” is defined as a property that has a setter and a getter;
* Whatever value “bar” is set to is ignored, and it is set to 23
* instead. The same could be achieved with an empty setter and
* a getter that always returns 23.
*/
"bar": {
"set": function () {
_bar = 23;
},
"get": function () {
return _bar;
}
}
}
}()));

/* 42 */
console.log(foo.bar = 42);

/* 23 */
console.log(foo.bar);

There is no way to write code strictly equivalent to the first one without
using additional variables/properties (to hold the original return value)
because repeated method calls and variable/property accesses need not return
the same value as before (although in this case it is safe to assume that
the value of the local variable “a” cannot be changed after it has been
assigned to). IOW, the code

function k ()
{
var a;

if (b.onScroll) b.onScroll();

if (b.getPageInView)
{
var a = b.getPageInView();
if (b.getPageInView())
{
F = a;
if (a)
{
document.getElementById("pageNumber").value = a;
}
}
}
}

is equivalent, but not strictly equivalent, because b.getPageInView() can
return a different value the second time.

It should also be noted that the conversion of “b.getPageInView” to a true-
value, if possible, does not necessarily mean that “b.getPageInView” can be
called. As I have explained often before, this test is, in general, both
insufficient and error-prone. See also jsx.object.isMethod ===
jsx.object.isHostMethod, and jsx.object.isNativeMethod() (the latter is
deprecated for trivial cases in favor of a simple “typeof x == "function"”).

--
PointedEars
FAQ: <http://PointedEars.de/faq> | <http://PointedEars.de/es-matrix>
<https://github.com/PointedEars> | <http://PointedEars.de/wsvn/>
Twitter: @PointedEars2 | Please do not cc me./Bitte keine Kopien per E-Mail.

Thomas 'PointedEars' Lahn

unread,
Mar 30, 2017, 12:14:01 PM3/30/17
to
JJ wrote:

> On Thu, 30 Mar 2017 18:48:38 +1100, Andrew Poulos wrote:
>>> which has me confused. Is the line
>>>
>>> b.getPageInView && (a = b.getPageInView()) && (F = a,
>>> document.getElementById("pageNumber").value = a);
>>>
> [snip]
>>
>> Or should I have said, is equivalent to
>>
>> if (b.getPageInView) {
>> a = b.getPageInView();
>> if (a) {
>> F = a;
>> document.getElementById("pageNumber").value = a;
>> }
>> }
>
> Yes, it's the same.

No, it is not.

Evertjan.

unread,
Mar 30, 2017, 1:07:17 PM3/30/17
to
to...@mountifield.org (Tony Mountifield) wrote on 30 Mar 2017 in
comp.lang.javascript:

>> After:
>>
>> F = 7;
>> a = 0;
>> if (a) {
>> F = a;
>> document.getElementById("pageNumber").value = a;
>> }
>>
>> F will be 7,
>>
>> while after:
>>
>> F = 7;
>> a = 0;
>> F = (F = a) && (document.getElementById("pageNumber").value = a);
>>
>> F will be 0;
>
> What's an initial assignment to F got to do with it? That wasn't in the
> original example. Nor was your outer assignment to F in the third line.

That does not matter, it shows both codes are not the same.

> Let's consider the original code piece by piece:
>
> b.getPageInView && (a = b.getPageInView()) && (F = a,
> document.getElementById("pageNumber").value = a);

[..]

Let's not

I am not responding to the exact code,
I am showing both codes are not the same.

That they get the same result in a specific instance,
where the value of F is unimportant, has nothing to do with it,
as is this nonsense:

a = 3;

and

a = 4;

are exactly the same if you do not use the value of a.


>> > If you believe
>> > it to be a wrong interpretation of the original code, why not provide
>> > a better one
>>
>> This is not a church,
>> faith does not come into coding,
>> faith being nonsense anyway.
>
> s/believe/consider/ or s/believe/think/. I was using "believe" in one of
> those meanings, nothing to do with faith.

You used, I expected, 'believe' to show you trust your analysis without
testing, which is dangerous in your own code, but undefentable if you try to
get people to understand a certain manner of coding.

> Sounds like you have an axe to grind regarding the latter.

You must be a good listener to sounds. ;-)

>> > , instead of the unrelated and simple example below?
>>
>> I try to teach to the best of my knowledge,
>> not take over the coding,
>> this NG not being a helpdesk.
>
> That's true, it isn't. But if you volunteer to respond, it doesn't help
> if you don't answer the question asked.

"if you volunteer to help"?

Nonsense, this is not a helpdesk,
and I don't "volunteer",
I respond because I want to respond.

I read in the somewhat convoluted code question the misunderstanding
of the both peculear and usefull working the "&&" binary operator.

And my response was to the group, not just to the OP.

John G Harris

unread,
Mar 31, 2017, 5:30:36 AM3/31/17
to
On Thu, 30 Mar 2017 18:13:07 +0200, Thomas 'PointedEars' Lahn
<Point...@web.de> wrote:

<snip>
> variable that holds a reference to an object
<snip>

The ECMAScript Standard says very clearly [1] that the value of a
property [2] can be an object. It also says, though not so clearly as
you need to review a cascade of abstract functions, that one object
can be the value of several different properties.

If this sounds peculiar think of it as a high level view. Its job is
to predict/specify the results of running an ECMAScript program. For
instance, when
var a = new Date();
var b = a;
var t = typeof b;
/* Code to display t in some way */
is executed the Standard predicts/specifies that
object
will be displayed. Saying how and why this was made to happen is not
the responsibility of the Standard.

Anyone who wishes to implement ECMAScript must ensure that the
implementation conforms to these requirements. The Standard does
not say that this must be done in any particular way.

One way to do it for a property that notionally holds an object
as its value is to hold a pointer to the object instead. I.e It
holds a reference_to_object value.

Another way to do it is for the property to contain a
reference_to_value. It points to the value, which is of any type.
The value can be a number, a string, an object, etc. This reference
is part of the internal structure of the property. It has nothing
to do with the type of the value. The value can now be shared by
several properties when this desired.

Saying that one of these ways is what is done is valid only when
talking about a particular product. It is not valid when talking
about all past, present, and future products that implement
ECMAScript.


[1] ES7 sec 6, especially the initial text of 6, 6.1, 6.1.7, and the
first entry in table 2 in 6.1.7.1

[2] Note that a variable is defined to be a property.

John

Thomas 'PointedEars' Lahn

unread,
Apr 2, 2017, 8:41:07 AM4/2/17
to
John G Harris wrote:

> [2] Note that a variable is defined to be a property.

The concept of a Variable Object of an execution context, with the
identifiers of variables declared in it as the names of its properties, was
superseded by the concept of a “VariableEnvironment” “Lexical Environment
whose EnvironmentRecord holds bindings created by VariableStatements within”
an execution context in ECMAScript Edition 5(.1) (2009-12, 2011-06).
See also ES 2016, § 8.3.

John G Harris

unread,
Apr 2, 2017, 2:05:13 PM4/2/17
to
On Sun, 02 Apr 2017 14:41:01 +0200, Thomas 'PointedEars' Lahn
<Point...@web.de> wrote:

>John G Harris wrote:
>
>> [2] Note that a variable is defined to be a property.
>
>The concept of a Variable Object of an execution context, with the
>identifiers of variables declared in it as the names of its properties, was
>superseded by the concept of a “VariableEnvironment” “Lexical Environment
>whose EnvironmentRecord holds bindings created by VariableStatements within”
>an execution context in ECMAScript Edition 5(.1) (2009-12, 2011-06).
>See also ES 2016, § 8.3.

True, I missed that, but variables have the same allowed Value types
as do properties:

ES7 Sec 8.1.1 Table 15 :
InitializeBinding(N, V)
Set the value of an already existing but uninitialized binding in an
Environment Record. The String value N is the text of the bound name.
V is the value for the binding and is a value of any ECMAScript
language type.

and

SetMutableBinding(N, V, S)
Set the value of an already existing mutable binding in an Environment
Record. The String value N is the text of the bound name. V is the
value for the binding and may be a value of any ECMAScript language
type.

"any ECMAScript language type" includes objects, but not references.
The Value of a variable can be an object, but not any kind of
reference.

John

Thomas 'PointedEars' Lahn

unread,
Apr 9, 2017, 11:00:51 PM4/9/17
to
John G Harris wrote:

> […] Thomas 'PointedEars' Lahn […] wrote:
>> John G Harris wrote:
>>> [2] Note that a variable is defined to be a property.
>> The concept of a Variable Object of an execution context, with the
>> identifiers of variables declared in it as the names of its properties,
>> was superseded by the concept of a “VariableEnvironment” “Lexical
>> Environment whose EnvironmentRecord holds bindings created by
>> VariableStatements within” an execution context in ECMAScript Edition
>> 5(.1) (2009-12, 2011-06). See also ES 2016, § 8.3.
>
> True, I missed that, but variables have the same allowed Value types
> as do properties: […]

Correct, but irrelevant. In the majority of cases, i.e. in the majority
of currently used implementations of ECMAScript, variables are _not_
properties; contrary to your statement. And without further qualification,
“ECMAScript” ought to refer to the current Edition of ECMAScript (here).

Your newsreader is broken: it has mangled properly declared and encoded
Unicode characters in my posting when you quoted it. See also RFC 5536,
section “MIME Conformance”.

John G Harris

unread,
Apr 10, 2017, 5:03:01 AM4/10/17
to
On Mon, 10 Apr 2017 05:00:46 +0200, Thomas 'PointedEars' Lahn
<Point...@web.de> wrote:

>John G Harris wrote:
>
>> […] Thomas 'PointedEars' Lahn […] wrote:
>>> John G Harris wrote:
>>>> [2] Note that a variable is defined to be a property.
>>> The concept of a Variable Object of an execution context, with the
>>> identifiers of variables declared in it as the names of its properties,
>>> was superseded by the concept of a ?VariableEnvironment? ?Lexical
>>> Environment whose EnvironmentRecord holds bindings created by
>>> VariableStatements within? an execution context in ECMAScript Edition
>>> 5(.1) (2009-12, 2011-06). See also ES 2016, § 8.3.
>>
>> True, I missed that, but variables have the same allowed Value types
>> as do properties: […]
>
>Correct, but irrelevant.

What are you on about? In my correction I quoted ES7 which clearly
states that a variable's value is restricted one of Undefined, Null,
Boolean, String, Symbol, Number, and Object, just like properties. The
value of a variable is *never* any kind of indirection.


>In the majority of cases, i.e. in the majority
>of currently used implementations of ECMAScript, variables are _not_
>properties; contrary to your statement. And without further qualification,
>“ECMAScript” ought to refer to the current Edition of ECMAScript (here).
<snip>

Again, what are you on about? I agreed that variables are properties
in old implementations and not in more recent implementations. But
that makes no difference. Either way, an object can be the value of a
variable, a 'reference' cannot.

John
0 new messages