Ronny Blom
Ronny Blom

Reputation: 149

Does indexOf != -1 return a Boolean?

I have just started learning Javascript and I have a specific question about a specific piece of code below. It is part of the lycanthrope's log in chapter 4 of Eloquent Javascript. Because of the specificity of my question I haven't included all the other code associated with this problem for I believe it isn't necessary to answer my question.

Please do let me know if this is considered 'bad practice' and I will make sure to ammend this and/or future posts to show more background.

In the code below the second line shows a return. So far I have learned that indexOf returns a positive number or zero if and only if it finds an occurence of whatever is passed in it. If no occurence is found it returns -1.

In this case it is followed by != -1, which I understand to mean "not equal to minus 1". That is clear to me.

What I do not completely understand is what the actual return in line 2 ends up being. Does it return a Boolean value of either true or false? Or does it return he actual index where the 'event' is found?

Further on, in the first if-statement, we see the hasEvent variable again. I read this statement as "If hasEvent(event, entry) is true then add 1 to the index.

Am I 'reading' this right and is the return in the second line indeed a Boolean?

function hasEvent (event, entry) {
  return entry.events.indexOf(event) != -1;
}

function tableFor (event, journal) {
 var table = [0, 0, 0, 0];
 for (var i=0; i < journal.length; i++) {
  var entry = journal[i] , index = 0;
  if (hasEvent(event, entry)) index += 1;
  if (entry.squirrel) index += 2;
  table [index] += 1;
}
 return table;
}

Thank you for your help and please tell me if I should have stated this question differently! I am trying to make sure I understand things before I move on!

Upvotes: 3

Views: 3338

Answers (4)

ctwheels
ctwheels

Reputation: 22817

Explanation

By default, the indexOf function returns the index location of the substring.

A bitwise shortcut can be used with indexOf as well as other functions:

  • ~ (bitwise not operator):
    • This works similar to ~x => -(x+1)

Simply checking against this value (for example using an if statement) yields true for non-zero values and false for zero.

If you need the actual boolean value instead, you can use the following: !!~. Here, the double exclamation !! is non-inverted boolean representation. Combining both essentially flips the result of indexOf, then converts it to boolean representation.

A better explanation of ~ can be found here. A better explanation of !! can be found here

Example

let s = 'abc'

/*
console.log(~s.indexOf('a'))  // -1
console.log(~s.indexOf('b'))  // -2
console.log(~s.indexOf('d'))  //  0

console.log(!~s.indexOf('a')) // false
console.log(!~s.indexOf('b')) // false
console.log(!~s.indexOf('d')) // true

console.log(!!s.indexOf('a')) // false
console.log(!!s.indexOf('b')) // true
console.log(!!s.indexOf('d')) // true

console.log(~~s.indexOf('a')) // 0
console.log(~~s.indexOf('b')) // 1
console.log(~~s.indexOf('d')) // -1
*/

// This one works
console.log(!!~s.indexOf('a'))  // true: 0 => -1 => false => true
console.log(!!~s.indexOf('b'))  // true: 1 => -2 => false => true
console.log(!!~s.indexOf('d'))  // false: -1 => 0 => true => false

Upvotes: 1

Daniel A. White
Daniel A. White

Reputation: 190905

Yep. Using ===, ==, !, !==, !=, >, >=, < or <= results in a boolean expression, which would return a boolean from hasEvent.

Upvotes: 6

David
David

Reputation: 218828

Comparison operators all evaluate to a boolean value.

More to the point, what this code is specifically doing is abstracting a comparison behind a function name. Any operation or set of operations which results in a value can be placed in a function which returns that value. Doing so is a common refactoring to make code more readable and understandable, as the name of the function can impart intuitive meaning on the operation being performed.

So instead of something like this:

if (a == b) {

}

you can have this:

if (someCondition(a, b)) {

}

So you can give a meaningful name to the operation (more meaningful than someCondition of course). As long as that function returns the same value as the code it replaces, logically there is no difference.

Upvotes: 1

Pointy
Pointy

Reputation: 413712

The != operator always has a boolean result.

A return statement followed by an expression returns the value of the expression, so the returned value of that function will be either true or false.

Upvotes: 8

Related Questions