Conditional statement with an assignment expression

A

Asen Bozhilov

Before few weeks ago Garret Smith payed attention for "Conditional
statement with an assignment expression":
<URL:http://groups.google.bg/group/comp.lang.javascript/msg/
9299befb874eb9a0>

He maintain theory for readable of code in statements like this one:

var x;
if (x = function(){})
{
x();
}

This is *complete* valid and *safe* approach:

| 11.13.1 Simple Assignment ( = )
| The production AssignmentExpression :
| LeftHandSideExpression = AssignmentExpression is evaluated as
follows:
| 1. Evaluate LeftHandSideExpression.
| 2. Evaluate AssignmentExpression.
| 3. Call GetValue(Result(2)).
| 4. Call PutValue(Result(1), Result(3)).
| 5. Return Result(3).

Step 4 return `undefined` independent from that is putted value or
not. `Simple Assignment` returned value from step 3.
All right but if that property for which i try to assign value has
{ReadOnly} attribute?

if (Object.prototype = function(){})
{
try {
Object.prototype();
}catch(e) {
/*Throwed from step 5 in 11.2.3 Function Calls */
window.alert(e instanceof TypeError);
}
}
 
D

David Mark

Before few weeks ago Garret Smith payed attention for "Conditional
statement with an assignment expression":
<URL:http://groups.google.bg/group/comp.lang.javascript/msg/
9299befb874eb9a0>

He maintain theory for readable of code in statements like this one:

var x;
if (x = function(){})
{
  x();

}

This is *complete* valid and *safe* approach:

Sure, it is technically sound. But it is considered bad form (style)
in that it can be mistaken for a test rather than an assignment. You
have to consider the programmer that comes next.
 
A

Asen Bozhilov

David said:
Sure, it is technically sound.  But it is considered bad form (style)
in that it can be mistaken for a test rather than an assignment.  You
have to consider the programmer that comes next.

Definitely. In other hands, that is the feature of language and it is
complete valid. You write program for competent people, which knows
what doing with tools in their hand. However, at all that is bad
practice, but there is not only problem with readability of code. The
main goal of that thread is exactly that. I just catch that and i
share with members of c.l.js.
Why internal `PutValue' doesn't return anything in explicit way? Why
`Simple Assignment` ever return value from step 3?
 
D

David Mark

Definitely. In other hands, that is the feature of language and it is
complete valid. You write program for competent people, which knows
what doing with tools in their hand.

Sure. I mean that it could be momentarily mistaken, requiring the
developer to pause and consider if it is a typo.
However, at all that is bad
practice, but there is not only problem with readability of code. The
main goal of that thread is exactly that. I just catch that and i
share with members of c.l.js.

Your efforts are appreciated.
Why internal `PutValue' doesn't return anything in explicit way?

The specs are what they are. :)
Why`Simple Assignment` ever return value from step 3?

Consider this "lazy" pattern:-

var myFunction = function() {
var fn;

// Scene missing--determine what function to use

return (myFunction = fn)(); // Replace and call
};

Of course, that last line is also considered bad form in some circles
(I'm neutral on that one). IIRC, JSLint considers it a "bad
invocation".
 
D

Dmitry A. Soshnikov

[snip]
Why internal `PutValue' doesn't return anything in explicit way? Why
`Simple Assignment` ever return value from step 3?

It can be useful in `return' statement. For example, memoization as an
optimization technique:

function getSomething() {
return something || (something = getSomethingWithHugeCalculation());
}

Sure this snippet can be replaced (and with more readability for some)
with the following:

function getSomething() {
if (!somethig) {
something = getSomethingWithHugeCalculation();
}
return something;
}

But I'm mentioning this just as example where it can take place.

In Ruby e.g. there's a special syntactic sugar for that (which I'd
like to see in ES too): ||=

def get_something
something ||= get_something_with_huge_calculation
end

Regarding exactly your case, there's no difference whether you assign
before `if' statement of inside its brackets. But, yep, psychological
this assignment inside the if's brackets can be treated as successful
result of assignment (which is should be Boolean in such thinking).
For do no make mistake programmer should know how `if' and assignment
work in ES.

Whether to use assignment inside the if's brackets or not - well, it
depends on complexity of the case (e.g. when you use foo = function ()
{} - nobody should think that this is comparison). But yep, it's can
be hard to read other programmers, especially for those which not well
understand how it works.

/ds
 
T

Thomas 'PointedEars' Lahn

It is probably safe as long as `x' does not refer to a host object prior to
assignment.
Sure, it is technically sound. But it is considered bad form (style)
in that it can be mistaken for a test rather than an assignment. You
have to consider the programmer that comes next.

It has been BCP since JavaScript 1.2 (Netscape Navigator 3.0) that
assignments be only used in conditional expressions where necessary, and
then only parenthesized (to work around the peculiarity in JavaScript 1.2
that the result of unparanthesized assignments was not the result of the
evaluation of the right-hand side but the boolean success status of the
assignment.¹)

So this should be at least

var x;
if ((x = function() {}))
{
x();
}

but, since

var x = function() {};
if (x)
{
x();
}

suffices, the latter should be preferred here. (Nota bene: JavaScript 1.2
does not support anonymous function expressions.)

That is different, for example, with

var x, y, z;

/* conditionally assign an object reference to x */

if (x && (y = x.p) && (z = y.q) && z.f)
{
z.f();
}

where as an optimization we can save the assignments to `y' and `z' if `x'
converts to `false' and access to `x.p' is likely to throw an exception,
and the assignment to `z' if `x.p' converts to false and `y.q' is likely to
throw an exception. This would otherwise require several (nested) `if'
statements.

That said, a type-converting test is usually insufficient to determine
whether it is safe that a property be [[Call]]ed, and it is error-prone
with host objects. Cf. several user-defined approaches of isMethod(),
isHostMethod(). And isNativeMethod(), IIRC. (Unfortunately, ES5 does not
appear to have managed specifying a *public* `IsCallable' method that can
be implemented so that it could be used in a backwards-compatible way.)


PointedEars
___________
¹ This is connected with the deprecation of the `language' attribute
of the SCRIPT element in HTML 4.01, where specifying e.g.
`language="JavaScript1.2"' changed program behavior in a
non-interoperable way.
 
M

Michael Haufe (\TNO\)

Sure, it is technically sound.  But it is considered bad form (style)
in that it can be mistaken for a test rather than an assignment.  You
have to consider the programmer that comes next.

Proper style dictates that an extra pair of parenthesis is required of
course:

var x;
if((x = function(){})){
x();
}

strict mode (in Fx at least) will throw a warning if its left out:
http://thenewobjective.com/temp/aWarning.html
 
A

Asen Bozhilov

Thomas said:
It has been BCP since JavaScript 1.2 (Netscape Navigator 3.0) that
assignments be only used in conditional expressions where necessary, and
then only parenthesized (to work around the peculiarity in JavaScript 1.2
that the result of unparanthesized assignments was not the result of the
evaluation of the right-hand side but the boolean success status of the
assignment.)

Thanks for your response and useful information about JavaScript 1.2
and Netscape Navigator 3.0. I have Netscape Navigator 3.0 on my local
machine. There are no distinct between parenthesized and
unparanthesized assignments.

function f(){}

window.alert(f.length); //0
if ((f.length = true))
{
window.alert(f.length); //0
}

window.alert(f.length = 10); //10
window.alert(f.length); //0

Only difference is:

var x = null;
if (x = true);

| Error: test for equality (==) mistyped as assignment (=)?
 
J

JR

Bad coding practice?
Best coding practice?
Brutally concocted proposition?

I really don't mind acronyms as long as they are commonplace. But since
you prefer "getElementById" over "$" in JavaScript, why not take the
time to spell out what you mean in human readable text?

ITA :D
BTW: The first hit google offers for BCP is "Best corporate publishing".

BCP == "Best Current Practice", according to:
http://encyclopedia.tfd.com/BCP
 
T

Thomas 'PointedEars' Lahn

Christian said:
Bad coding practice?

That this was not meant can be determined from the context in which it was
said.
Best coding practice?

Close enough. Best _Current_ Practice was meant.
Brutally concocted proposition?
LOL

I really don't mind acronyms as long as they are commonplace. But since
you prefer "getElementById" over "$" in JavaScript, why not take the
time to spell out what you mean in human readable text?

I assumed everyone interested would be familiar with it, and those who
would not understand would not hesitate to ask. And I have been right.
BTW: The first hit google offers for BCP is "Best corporate publishing".

Here it is "Airport parking with BCP" :)

When it doubt, first try a dictionary entry, like

<http://de.wikipedia.org/wiki/BCP>

So you see it is an acronym that is quite commonplace after all.

Happy New Year, BTW.


PointedEars
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top