From: Ivan S on
On May 10, 1:18 pm, "Dmitry A. Soshnikov" <dmitry.soshni...(a)gmail.com>
wrote:
> Theoretically or practically? If practically, you can test it yourself
> in every possible implementations and provide us with the results (maybe
> it will be useful for someone).
>
> In theoretically, for e.g. ES3 see 11.9.3 and 11.9.4. Let's compare them
> (the steps which are essential for our case -- when operands have _the
> same_ types such as in mentioned `typeof` check):
>
> 11.9.3 The Abstract Equality Comparison Algorithm:
>
> 1. If Type(x) is different from Type(y), go to step 14.
> 2. If Type(x) is Undefined, return true.
> 3. If Type(x) is Null, return true.
> 4. If Type(x) is not Number, go to step 11.
> 5. If x is NaN, return false.
> 6. If y is NaN, return false.
> 7. If x is the same number value as y, return true.
> 8. If x is +0 and y is -0, return true.
> 9. If x is -0 and y is +0, return true.
> 10. Return false.
>
> And now the strict one:
>
> 11.9.6 The Strict Equality Comparison Algorithm
>
> 1. If Type(x) is different from Type(y), return false.
> 2. If Type(x) is Undefined, return true.
> 3. If Type(x) is Null, return true.
> 4. If Type(x) is not Number, go to step 11.
> 5. If x is NaN, return false.
> 6. If y is NaN, return false.
> 7. If x is the same number value as y, return true.
> 8. If x is +0 and y is -0, return true.
> 9. If x is -0 and y is +0, return true.
> 10. Return false.
>
> We can omit step 1, because in our case types are equal -- we have
> String type.
>
> And then you can see that both algorithms are completely equivalent --
> (word for word!).
>
> So this is a big (and that is petty -- a wide spread) misconception. And
> this misconception is obtruded by the _subjective meaning_ of some
> authority. No more, no less. I repeat several times, that checks with
> `typeof` comparing with strings and using === just looks ridiculous.
>
> There is no any sense to use === with such checks. Because there is no
> logical answer on:
>
> (1) you know that `typeof` always produces string;
> (2) you (yourself, by your own hands, but nobody else) compare this
> result with a string.
>
> Is there any reason (except "I just like", "that's to keep common
> stylistics", "to be consecutive") to use ===?
>
> Of course, if you accept it with reasons-"exceptions" which I just
> mentioned -- that's your choice and your right. But please (I'm asking
> everyone), let us don't call == as a "bad practice" and don't say that
> this is about avoiding errors and etc. arguing (trying to argue)
> _logically_.
>
> This misconception is wide spread in _every_ popular framework.
>
> Recently, I was reviewing one book (which should appear soon on
> bookshelves) and there also == is named as a "bad practice" and
> everywhere is used === including `typeof` with a string comparison on
> the right hand side. (although, as a whole, the book is quite good with
> professional approach). I recommended (if the author still want to keep
> the general common stylistic using === everywhere), just to make a
> _small note_ such as: "but in some case, e.g. with typeof operator when
> we compare its result with strings, === is obsolete".

Thanks for your answer. I wasn't trying to imply that loose comparison
is bad practice, I was asking with logical presumption. Thanks again
for your tehnical explanation! :)



Ivan
From: Dmitry A. Soshnikov on
On 10.05.2010 16:17, Tim Streater wrote:
> In article<hs8q9m$ph$1(a)news.eternal-september.org>,
> "Dmitry A. Soshnikov"<dmitry.soshnikov(a)gmail.com> wrote:
>
>> On 10.05.2010 15:18, Dmitry A. Soshnikov wrote:
>>
>> [...]
>>
>>> This misconception is wide spread in _every_ popular framework.
>>
>>
>> Yeah, forgot. That's at the same time when they fight trying to save
>> every byte minimizing/obfuscating scripts. And everywhere using === they
>> loose this one byte every time :D
>
> Hey Dmitry you can save a byte every time by spelling "lose" as "lose"
> (correct) rather than "loose" (incorrect and completely different word)
> :-)
>

Ah, great :P Thanks!

(sorry for English typos).

Dmitry.
From: nick on
On May 10, 3:21 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
> nick wrote:
> > What's the "best" way to determine if a variable is defined?

> Depends. If conditional assignment results in an object value
> [...] then why not use boolean conversion?

> if(x) { [...]

True, I guess I should have mentioned it for the sake of completeness.
I'm really more concerned with undefined vs. not undefined ATM, but
this would be good to include in a FAQ entry or something, along with
'in'.

> Identifiers that are declared with var get DontDelete, so don't worry
> about the case where they were deleted -- they can't be.

Interesting. So deleting them just leaves their value as-is, huh?

The console in Chromium tricked me. Look at this:

var x=5; alert(x); delete x; alert(x);
// alerts "5"
// throws ReferenceError: x is not defined

I figured I had successfully deleted the var. But this line acts
totally different:

(function(){var x=5; alert(x); delete x; alert(x);})()
// alerts "5" twice
// function returns undefined as normal

Looks like there's some serious black magic being performed by the
console in the first example.

> For other values, it is useful to make different checks, depending on
> what the code needs ot know. [...]

Agreed.

> >   function isDefined (v) { return (v !== void 0) }

> That tells if a value is not undefined. The isDefined function in the
> general sense does not provide any advantage over an inline check.

That's true; If there's going to be a function call the function could
just be a no-op (returning undefined).

> It does not say, in the general sense, if `v` has been declared,

What do you mean? 'v' is declared as an argument to isDefined, right?
That was sort of the point of this example.

> does not say if has been assigned a value (undefined is a value), does not
> say if `v` is a variable, a property of something, the result of trying
> to get a property that was not available.

Ok, I see what you're getting at.

> Consider that, given function scope:

> (function(){
>    var undef, myVar;
>   //...
>    var isDef = isDefined(myVar);
>    var isDef2 = myVar !== undef;
> })();

Hmm, I'm not totally sold. If we're going to do it like that why not
just shadow the global undefined and use that?

> For the cost of a function call, plus organizing and managing that
> function, it is not worth it.

You are probably right. That function was not really the ultimate
point of the OP, it was just an example of a way to check for things
having a value of undefined (inline or otherwise) using the syntax
that I liked the most of the three examples above.

Still, I sort of like the idea of encapsulating it in a function.
David's macro idea is starting to sound pretty good...

//#define UNDEFINED void 0
//#define IS_DEFINED(v) (v !== UNDEFINED)

That should do it. :D
From: Ry Nohryb on
On May 10, 10:32 pm, nick <nick...(a)fastmail.fm> wrote:
> On May 10, 3:21 am, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
>
> > Identifiers that are declared with var get DontDelete, so don't worry
> > about the case where they were deleted -- they can't be.
>
> Interesting. So deleting them just leaves their value as-is, huh?

The delete operator is intended to delete *properties*of*objects* not
vars, and only global vars happen to be properties of an object (of
the global object). Applying delete to a non-global or to a non-
existent var will just do nothing.

A global var "x" exists if ("x" in window) is true (in any browser
except probably in Microsoft's Internet Explorer due to another of its
long long list of long standing never fixed / won't fix bugs). The
existence of a local var "x" is a lot harder to detect unequivocally.
--
Jorge.
From: VK on
On May 11, 1:32 am, Ry Nohryb <jo...(a)jorgechamorro.com> wrote:
> The delete operator is intended to delete *properties*of*objects* not
> vars, and only global vars happen to be properties of an object (of
> the global object). Applying delete to a non-global or to a non-
> existent var will just do nothing.

Applying delete to window properties or Javascript variables leads to
run-time error in IE. The *only* legal use of delete operator is for
Object instances, properties of Object instances and for elements of
Array instances. The docs are pretty explicit on it though:
http://docs.sun.com/source/816-6408-10/ops.htm#1045837

About undefined it is worth to mention IMO the most sick and bizarre
Javascript feature: the possibility to assign undefined value so
instantiating variables with value "I am not instantiated", see
"undefined vs. undefined" discussion at
http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/60004636376462c/

The purpose and the meaning of it remain a mystery to me, I assume
some minds were severely distracted at the time of introducing this
feature. Respectively Javascript has two undefined values with
different behavior but without an easy way to distinguish them:

var foo = undefined;

alert(typeof foo); // "undefined"

alert(foo); // "undefined"

alert(typeof bar); // "undefined"

alert(bar); // "bar is not defined" run-time error

Lucky this has purely theoretical importance: the idioticy of
assigning "not assigned" value, so keeping the identifier in the scope
yet forcing it to say "I don't exist", cannot be met in any descent
code.