2

In these example I am ruining a function with conditions;

function validPrice(price)
{
    if(price=="" || price==0 || price==null || price==undefined )
    { 
        //do something
    }
    else
    {
        // do something different
    }
}
var priceNew = $("li#listedProd").attr("price"); 

validPrice(priceNew);

My question is what are the different in these condition price=="" || price==0 || price==null || price==undefined

1
  • 6
    you can replace all of that by !price Commented Aug 16, 2014 at 19:24

3 Answers 3

4

Whoever first wrote that code was either

a) Being very defensive against future use. b) Didn't understand how attr works.

The method attr (or the underlying call of getAttribute will return either

  • A string value, of the attribute is found
  • null, if it is not.

Importantly, should there have been a 0 value, it would be a string 0, and thus not caught in the test below -- caught against the price == 0 test because the system would have automatically converted it to a number as part of the == compare.

if(price=="" || price==0 || price==null || price==undefined )

And, due to the way that conversions work internally, those tests don't work as intended. == and === are different. It should be:

if(price === "" || price === 0 || price === null || price === undefined )

All of which can easily be reduced to simply "price" due how how coercion to boolean work:

if (!price) 

Or, if you want to catch "0" values

if (!price || +price === 0)

(the +price forces price to be a number, so we catch 0 0.00 and other variations.)

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you i think this is great digestive answer
It should be coercion to boolean, not cohesion
@Simlofi: The price == null and price == undefined are performing identical tests. Don't do price === null || price === undefined either because it's unnecessarily verbose. Just do one of the first two when the situation calls for it.
3

Let's look at your conditional statement term-by-term:

price == ""

This is true if price is the empty string, and false otherwise.

price == 0

This is true if price is the integer 0, the string "0", or the empty string, and false otherwise. You should change this comparison to price === 0 if you want to catch when price is the integer 0.

price == null

This is true if price is passed to your function and is of the type null, and false otherwise.

price == undefined

Note: You should probably make this comparison via price === undefined to see that price is both undefined and has the type undefined.

This is true if price is not passed to your function, or if price is otherwise undefined, and false otherwise.

I would recommend just making the entire conditional statement !price:

function validPrice(price) {
    if (!price) { 
        //do something
    }
    else {
        // do something different
    }
};

var priceNew = $("li#listedProd").attr("price"); 

validPrice(priceNew);

5 Comments

price == 0 - This is true if price is the integer 0, and false otherwise. Not exactly. The use of == here would return true even if the price is a string equals "0". To make sure the variable type is considered, use === instead.
Noted. I've added an edit to my answer above clarifying this point.
price == 0 also returns true if price is "", false and some other things. price=="" || price==0 is almost redundant and so is price==null || price==undefined.
so in coding you mean var price == "" and price ==0 are not the same thing
Great comments, I've updated my answer with all of these clarifications. Thanks @Volune.
0

EDIT added definitions

JavaScript has 2 operators that test for equality (and conversely 2 operators that test for inequality.)

  • A strict equality comparison (e.g., ===) is only true if the operands are of the same type AND if the object is actually the same object, or the primitives have the same value (e.g., 0 === 0, and 'a' === 'a' are both true). *Note there is a slight exception to this rule for NaN (see below)

  • An abstract equality comparison (e.g. ==) converts the operands to the same Type (if they aren't already) before making a strict equality comparison. If however one of the operands is null or undefined, the comparison is true if and only if the other operand is either null or undefined.

So in short the == equality operator is considered by many to be unsafe. To see the difference checkout http://dorey.github.io/JavaScript-Equality-Table/

For instance '' ==: 0, '', [], false, [[]]

And 0 ==: false, 0, '0', '', [], [[]], [0]

While null ==: null, undefined

And finally undefined ==: null, undefined

It is better to use strict equal === or just test for a falsey value ('', 0, undefined, null, false)

if (!price) { //do something }

Below I have provided more details about strict vs abstract equality comparison

details came from ECMA-262, Edition 5 11.9.1 Summary of strict equality algorithm

1. If typeof(x) is different from typeof(y), return false.
2. If typeof(x) is undefined, return true.
3. If x is null, return true.
4. If typeof(x) is number, then
    a. If x is NaN, return false.
    b. If y is NaN, return false.
    c. If x is the same Number value as y, return true.
    d. If x is +0 and y is -0, return true.
    e. If x is -0 and y is +0, return true.
    f. Return false.
5. If typeof(x) is string, then
    a. If x and y are exactly the same sequence of characters (same length and same characters in
corresponding positions), return true.
    b. Else, return false.
6. If typeof(x) is boolean, then
    a. If x and y are both true or both false, return true.
    b. Else, return false.
7. If x and y are the same Object value, return true.
8. Return false.

And ... details came from ECMA-262, Edition 5 11.9.1 Summary of Abstract Equality Algorithm

1. If typeof(x) is the same as typeof(y), then
    return the result of performing strict equality comparison algorithm x === y.
2. If x is null and y is undefined, return true.
3. If x is undefined and y is null, return true.
4. If typeof(x) is number and typeof(y) is string,
    return the result of the comparison x == Number(y).
5. If typeof(x) is string and typeof(y) is number,
    return the result of the comparison Number(x) == y.
6. If typeof(x) is boolean, return the result of the comparison Number(x) == y.
7. If typeof(y) is boolean, return the result of the comparison x == Number(y).
8. If typeof(x) is either string or number and typeof(y) is object,
    return the result of the comparison x == [[ToPrimitive]](y).
9. If typeof(x) is object and typeof(y) is either string or number,
    return the result of the comparison [[ToPrimitive]](x) == y.
10. Return false.

[[ToPrimitive]] is an internal function call

Bullets 8 and 9 basically mean that objects are converted like object.valueOf().toString() so:

{} == '[Object object]' { hi: 'hi'} == '[Object object]' { valueOf: function(){ return 0; }} == 0 { toString: function(){ return 'hi'; }} == 'hi' { valueOf: function(){ return 0; }, toString: function(){ return 'hi'; }} == 0

Full ecma-262/5.1/#sec-11.9 spec

1 Comment

@user2864740 you downvoted seconds after i posted, while i was still editing it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.