The issue with
function longest(first, second) {
if (first.length >= second.length) {
return first;
} else {
return second;
}
}
if you call it as longest('Alice')
is that it spews out an error:
TypeError: Cannot read property 'length' of undefined
because second is undefined
, and properties of undefined
like .length
can not be read.
undefined
is actually a thing in Javascript rather than an automatic error like in many other languages. We'll come back to that soon...
The purpose is to get you to thinking about how to fix the function. If the function assigned a blank string in place of undefined, the blank string would have a length, 0, that could be read.
In Javascript the ||
operator can be used to assign default values to missing variables as follows:
function longest(first, second) {
var defaultValue = '';
var first = first || defaultValue;
var second = second || defaultValue;
if (first.length >= second.length) {
return first;
} else {
return second;
}
}
Now if either first or second is undefined, they will be replaced locally with the value of the defaultValue
variable, which here is set to the empty string ''
.
The empty string is not an undefined value, it is a string that contains no characters. It has a length, and that length is zero. Now the if statement will not fail when an undefined value is passed.
Now longest('Alice')
yields 'Alice'
Bugs
Unfortunately the assignment as shown does not teach you enough about Javascript. It is probably worth knowing about a peculiar Javascript feature: any property whether it is called 'length' or something else can be read from existing objects that do not have that property. This may lead to undesired behavior. The result is a value called undefined
, which is a value that things can be in Javascript.
When undefined
is compared with a number, the result is always false
. Mathematically that's normally impossible. We normally think that if x>1
is false
, then x<1
must be true
or x
is 1
. That kind of logic does not work for undefined
.
When undefined
is compared with undefined
the result is also false
, unless it is an equality test which is true
.
Why does this matter? It relates to bugs in the longest()
function above. Number inputs are one example. Strings representing numbers have a length but numbers do not have a length. Reading the length of a number yields undefined. And comparing undefined with a defined number is false. That means we can do this:
longest(1,100)
returns 100
Correct.
but
longest(100,1)
returns 1
OOPS.