最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - What is the result of a comparison between an integer and an object? - Stack Overflow

programmeradmin4浏览0评论

What is JavaScript's behavior when paring objects with integers? For example:

var result = { test: 'blah' };
if (result < 0) {
    // when is this portion processed?
}

I am currently working with a result variable that could be either an integer (error code) or an object holding further details.

I guess I could use parseInt() or parseFloat() but I'm quite interested in knowing the shortest possible way to handle these situations...

What is JavaScript's behavior when paring objects with integers? For example:

var result = { test: 'blah' };
if (result < 0) {
    // when is this portion processed?
}

I am currently working with a result variable that could be either an integer (error code) or an object holding further details.

I guess I could use parseInt() or parseFloat() but I'm quite interested in knowing the shortest possible way to handle these situations...

Share Improve this question edited Dec 17, 2017 at 20:24 codejockie 10.9k4 gold badges48 silver badges57 bronze badges asked Dec 17, 2017 at 9:22 user9109298user9109298 4
  • 4 Did you try it? – JJJ Commented Dec 17, 2017 at 9:24
  • 1 Hello Josan. Yes, but I'm wondering in there are any differences between JS engines and if a general rule has been defined... – user9109298 Commented Dec 17, 2017 at 9:26
  • An alternative strategy is to have result always be an object with an error code (that is eg. 0 when no error has occurred) and a value. This way you don't give the value of result itself two responsibilities. – Grav Commented Dec 17, 2017 at 14:40
  • 1 @groslouis Looking at the ECMAScript 2015 specification (specifically sections 12.9,3, 7.2.11, 7.1.1, 19.1.3.6, and 7.1.3.1), it would appear that the correct result of { 'test': 'blah' } < 0 should always be false in conforming implementations. The same should apply for any object with the standard toString and valueOf functions in the Object prototype. – LegionMammal978 Commented Dec 17, 2017 at 15:09
Add a ment  | 

6 Answers 6

Reset to default 6
var result = {test: 'blah'};

if(result) {
   if (typeof result === 'object') {
     // do something
   } else if (typeof result === 'number') {
     // do something
   }
}

I'm wondering [...] if a general rule has been defined

Yes. The rules are described in JavaScript specification. For your example:

{ test: "blah" } < 0

I have highlighted the sections and rules involved:

11.8.5 The Abstract Relational Comparison Algorithm
[...]
1.a Let px be the result of calling ToPrimitive(x, hint Number).

The expression { test: "blah" } ends up as "[object Object]"

3.a Let nx be the result of calling ToNumber(px).

The expression "[object Object]" ends up as NaN

3.c If nx is NaN, return undefined.

The result of algorithm is undefined.

11.8.1 The Less-than Operator ( < )
[...]
6. If r is undefined, return false. Otherwise, return r.

The end result is false.

Javascript will call the valueOf() method on the object automatically if you are paring it to an integer. Similarly, when paring to a string, the toString() method is used.

If you are not the creator of the object, there may or may not be a valueOf function, so the behavior of using a parison operator can be unexpected if you haven't created the objects or done some additional testing logic and are just paring objects and integers.

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators

The following snippet shows some parisons in action.

var five = { 
  value: 5, 
  valueOf: function() { 
    return this.value 
  } 
};

var billion = { 
  value: 1000000000
};

console.log ( five.valueOf() );
console.log ( billion.valueOf() );
console.log ( billion > five );
console.log ( NaN > five );
console.log ( 6 > five );
console.log ( 4 > five );

Document on developer.mozilla says that JS parison logic when operand A is an Object and operand B is a Number, is defined this way:

ToPrimitive(A) == B

where

ToPrimitive(A) attempts to convert its object argument to a primitive value, by attempting to invoke varying sequences of A.toString and A.valueOf methods on A.

Additionally, Mozilla JavaScript Reference states :

If the method is not overridden in a custom object, toString() returns "[object type]".

and

Starting in JavaScript 1.8.5 toString() called on null returns [object Null], and undefined returns [object Undefined], as defined in the 5th Edition of ECMAScript and a subsequent Errata.

So it is reasonable to say that in case of parison with a Number, an Object will always be converted to a String.

Which is then handled this way:

ToNumber(A) === B

ToNumber(A) attempts to convert its argument to a number before parison. Its behavior is equivalent to +A (the unary + operator).

Finally, Unary Plus doc states that:

If it cannot parse a particular value, it will evaluate to NaN.

Same doc on developer.mozilla present a summary table showing that paring a Number with NaN does always return false.

So, unless in scenarios raised by @JasonB, the given code should work.

However, to avoid any error due to data-structure, the answer given by @ John Kennedy is to be preferred.

You can check if result is an integer with result.isInteger() first and then perform whatever is needed if it is or treat it as an object otherwise.

I suggest that you test the type of the result variable to determine if its a number or an object.

Test for an Object:

typeof result === 'object'

Test for a Number:

Number.isInteger(result)

发布评论

评论列表(0)

  1. 暂无评论