var myArray = [1, 6, 2, 9, 2, 5, 9, 9, 3];
var nines = [];
var index = -1;
while ((index = myArray.indexOf(9, index + 1)) != -1) {
nines[nines.length] = index;
}
console.log(nines); //Writes 3, 6, 7
We can now rewrite our lucky lottery number generator using th e m ethods sort()
and indexOf(). We will also use your suggestions from page 178, Mike, to reduce
the length of the p rogram. The program is now consid erably shorter, and with an
additional sor ting feature:
var drawnNumbersList = [];
var i, n;
for (n = 0; n < 6; n++) {
do {
drawnNumbersList[n] = Math.floor(Math.random() * 54) + 1;
} while(drawnNumbersList.indexOf(drawnNumbersList[n]) < n);
}
drawnNumbersList.sort();
document.write(drawnNumbersList);
What’s wrong with the sorting? We got the numbers 10, 25, 3, 31, 4, and 48.
Mike: The elements are arranged alphabetically, are n’t they?
Professor: That’s right. The sort() method compares strings.
Maria: Is sort() therefore useless for us?
Professor: Not necessarily. We just have to do some more work to make it useful for
our purpose. We need to provide a criterion by which the array elements should be
compared. Next week you’re going to learn how to do that.
9.5 String Object
Professor: Next on our agend a is the String object. Strings could be seen as arrays
of cha racters, which makes String quite similar to the Arr ay object. The main dif-
ference between both is tha t you can chan ge the value of array elements but there’s n o
way you can alter parts of the text stored in an existing string. We say that strings are
immutable. The following example demonstrates that:
//Constructs a String object:
var myString = new String("Testing, testing...");
var letter = myString[3]; //Copies the fourth letter ("t")
myString[0] = "7"; //No-go: strings are immutable
180 Meeting 9. Understanding Arrays and Strings
The String() constructor is q uite straightforward—yo u simply pass any value to be
converted to a string as its argument.
In the second line , I used an index access operator ([] ) to access the fourth character,
which is the letter “t, and assign its value to letter. T he last line of the exam-
ple, however, doesn’t work. It won’t change the myString string because strings are
immutable. Note that this last line doesn’t gene rate an erro r, though. It simply fails
silently.
Maria: That’s odd, I could swear that we’ve already changed a value o f a string,
haven’t we?
Professor: Technically, yes. You can assign a whole new text to a string:
myString = "Something new";
But that’s not the sam e string any more. It’s not even an object. The above line didn’t
change the object value but created a whole new data instance, which is now a string
primitive. The next example d emonstrates that:
var myString = new String("Original");
console.log(typeof myString); //Writes object
myString = "Something new";
console.log(typeof myString); //Writes string
Anyway, from a practical point of view, it is important that you cannot chan ge ju st a
portion of a string in the way you can change individua l elements of an a rray.
Just like arrays, strings also have the length property, which holds th e number of
string ch aracters.
You can manipulate strings using one of the many methods of the String object.
These are some examples:
var myString = new String("Still testing...");
myString.indexOf("S") //Returns 0: upper-case "S"
myString.indexOf("s") //Returns 8: lower-case "s"
myString.indexOf("til") //Returns 1
myString.indexOf("TEST") //Returns -1: not found
myString.slice(10) //Returns "ing..."
myString.slice(2, 4) //Returns "il"
myString.toUpperCase() //Returns "STILL TESTING..."
myString.toLowerCase() //Returns "still testing..."
Because strings are immutable, the methods tha t modify the strin g only return a mod-
ified string—the original string is not altered in any way. Do you want any extra
explanation of the above examples?
9.5. S tring Object 181
Mike: I see that indexOf( ) works the sam e as indexOf() of the Array object except
that it can search not only for a single chara cter but also for the whole sequence of
characters. toUpperCase () and toLowerCase() are also obvious, but I d on’t think
I can decipher slice(), except that it returns a part of the original string. How does
it work?
Professor: slice() is used to extract a substring from the original string. It accepts as
an argument the index of the first charac te r to be included in the extracted substring .
The returned substring then contains a ll the cha racters from the spe cified character
to the end of the orig inal string. With the second argum ent, which is optio nal, you
determine the last character to be included in the substring. Note that the last chara cter
will be the one with the index one smaller than the given second argument.
The fact that many string methods retu rn a string a llows for a so -called method chain-
ing. You c an use a property or method directly on a returned value without using any
intermediate variables. Here are two examples of method chaining:
myString.toUpperCase().slice(2, 4) //Returns IL
myString.slice(2, 4).length //Returns 2
Let’s top o o ur discussion about strings with an example that rounds a number to two
decimal places. If the number is an integer, or has only a single dec imal plac e, then
the program should still produce a result with two decimal places. For example, 7.928
should end up as 7.93, 10 a s 10.00, an d 5.2 as 5.20. Any ideas on how to pull that one
o?
Maria: Math.round() come s first to my mind but it rounds to the nearest integer.
Besides, I expect that we’re going to work with strings, aren’t we?
Professor: We’ll make use of them, all right. Please, go on.
Maria: I can multiply a number by 100, then Math.round() it, and divide it back by
100. That’s OK if a number h as at least two decimal places, otherwise
.... No, that’s
not going to work. Instead of dividing, I can simply insert a dot. Like this:
var number = 12.4;
var dotPosition;
var result;
number *= 100;
number = Math.round(number);
number = String(number);
dotPosition = number.length - 2;
result = number.slice(0, dotPosition);
result += ".";
result += number.slice(dotPosition);
console.log(result); //Writes 12.40
Mike: I think that you cannot use number.length because n umber is a primitive
string and not a String object. You forgo t to use new w ith the String() constructor.
182 Meeting 9. Understanding Arrays and Strings
If I remember correctly, String() called w ithout a new operator is a type conversion
function that returns a primitive string.
Professor: That’s true, altho ugh it doesn’t really matter whether number is a string
primitive or object. Whenever you use a property or method on a string primitive, a
temporary String object called a wrapper object is c reated automatically behin d the
scenes. When you stop usin g the object’s properties and methods, the wrapper object
is destroyed. This eectively blurs the distinc tion between primitive and object string
types and you can use a primitive string as though it was an object:
var s = "I am primitive";
console.log(s.length); //Writes 14
console.log(s[3]); //Writes m
console.log(s.slice(0, 4)); //Writes I am
Still, th ere is an important dierence between primitive strings and object strings.
Consider the next code fragment:
var strObject1 = new String("Something");
var strObject2 = new String("Something");
console.log(strObject1 == strObject2);
console.log(strObject1 == "Something");
What do you think the result will be?
Maria: I remember that objects are compared b y reference. In th e above example we
compare objects that have equal values but are distinct. Both compar iso ns therefore
return false.
Professor: The first comparison indeed returns false. Th e second comparison, how-
ever, has a primitive string on one of its sides. Because of tha t, the string object
strObject1 on its other side is converted to a primitive string and both primitives are
compared by value, wh ic h returns true.
The same object-to-primitive conversions take place when yo u compare string objects
using greater-than or less-than operators. Let me summarize the rules for you:
If both operands of the equality operator (==) are string obje cts, then the opera-
tor returns true if and only if both operands refer to one and the same object. If
they refer to dierent objects, the return value is fa lse even when both objects
hold iden tical strings. No object-to-primitive conversion occurs here.
If one operand of the equa lity ope rator (==) is a primitive string and the other is
an ob je ct string, then the object is converted to a primitive before comparison.
Both primitives ar e then compared by value.
If either operand of a comparison operator >, <, >=, or <= is a string object,
then that object is converted to a string primitive. The string primitives are then
compared alphabetically.
9.5. S tring Object 183
Of course, just the oppo site of what was said for the equality operator is true for the
inequality o perator (!=).
Mike: You didn’t mention the strict equality (===) and inequality (!==) operators. I
guess that no conversion is made with them.
Professor: That’s true .
Note that string pr imitives might not compare as equal even if they appear equal. They
may be encoded using dierent encoding rules. But that isn’t something you should
worry about right now.
Mike: How ca n you compare two string objects by value if you want to find out
whether they are equal?
Professor: You can use the toString() method, which returns a primitive string
representation of an object. Note that other object types also have th is method , which
is usually called automatically by the system whenever a conversion to a strin g is
necessary. But you ca n call toStr ing() explicitly as well. For example, you can
compare two string objec ts like this:
var s1 = new String("I’m the same");
var s2 = new String("I’m the same");
console.log(s1 == s2); //Writes false
console.log(s1.toString() == s2.toString()); //Writes true
Maria: What if I compare a string object to a number?
Professor: Wha t do you think?
Maria: Perhaps the string object should convert to a string primitive first. According
to w hat you have told us so far, this sounds like the most reasonable solution to me. I
guess that after that the stand ard rules for primitive types apply, which means that the
string primitive will further convert to a number.
Professor: Exactly.
Mike: I remember seeing a Number object somewhere. Could it be th at JavaScript
can cre ate a wrapper object for a primitive number as well?
Professor: You’re quite right about that.
Mike: If the Numbe r object also has the toString() method, then we could rewrite
the sixth line of our rounding-to-two-decimals example on page 182 like this:
number = number.toString();
Professor: Yes, that is indeed possible. You decide which one you p refer.
184 Meeting 9. Understanding Arrays and Strings
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.15.129.90