This book isn’t meant to teach you JavaScript; it’s meant to be a survey of a framework that acts as JavaScript’s “standard library.” Prototype sticks utility methods in appropriate nook
Trang 1var retotal = totaler.updateTotal.bind(totaler);
retotal();
The method runs, error free
Function#bindis most useful when dealing with event assignment Switching the
con-text in which an event handler runs is something we’ll need to do quite often in the
chapters to come
Summary
We’ve taken a brief glance at two useful models for DOM scripting: functional and
object-oriented programming These models, in fact, go far beyond contrived code patterns;
they’re manifestations of core features of JavaScript Functional programming is right at
home in the event-driven world of browser scripting; OOP is a corollary of JavaScript’s
principles of mutability and scope
You’ll be able to appreciate these pillars of JavaScript coding philosophy as we delve
into the use cases presented in Part 2
C H A P T E R 7 ■ A D VA N C E D J AVA S C R I P T: F U N C T I O N A L P R O G R A M M I N G A N D C L A S S - B A S E D O O P 165
Trang 2Other Helpful Things:
Useful Methods on Built-Ins
decided to write it anyway This book isn’t meant to teach you JavaScript; it’s meant to be
a survey of a framework that acts as JavaScript’s “standard library.” Prototype sticks utility
methods in appropriate nooks and crannies, some of which are simply too general to
have been addressed in an earlier chapter
This chapter, then, will explore the convenience methods that Prototype adds to
built-in objects Many of them are used within Prototype itself, but they’re likely to be
useful in your own code as well
Using String Methods
I’m at a loss here What can I say about strings? Strings in JavaScript bear good news
and bad news The bad news is that many of the conveniences that other languages
possess for dealing with strings simply aren’t present in JavaScript The good news is
that, as we’ve done elsewhere, we can leverage the hackability of the language to fix this
shortcoming
String Utility Methods
Prototype adds a bagful of useful instance methods to strings Some you’ll use every day;
some rarely, if ever But they’re there in case you need them
The gsub, sub, and scan Methods
These first three methods all involve searching for text in a string and doing something
with the result
167
Trang 3At first glance, String#gsubwould appear to be redundant—it behaves just like String#replaceand has a weirder name At second glance, though, it will become your method of choice for string substitution
replace, it takes two arguments: a pattern and a replacement The pattern can be a string
or a regular expression; the replacement can be a string or a function
Let’s look at the simplest case—both arguments as strings:
"Never, never pour salt in your eyes.".gsub('never', 'always');
//-> "Never, always pour salt in your eyes."
change that first argument to a case-insensitive regular expression
■ Tip Do regular expressions intimidate you? If so, this section might not be for you Type “regular expres-sions” into your favorite search engine if you need a crash course
"Never, never pour salt in your eyes.".gsub(/never/i, 'always');
//-> "always, always pour salt in your eyes."
OK, that problem was easy to solve—JavaScript allows us to ignore case by using
“never” has a capital N, since it’s the first word of the sentence We need to ensure that
a capitalized word has a capitalized replacement
To do this, let’s get a little cleverer with our regular expression We can experiment
accepts a string, applies the given regular expression against it, and returns an array of matches:
/never/.exec("Never, never pour salt in your eyes.");
//-> ["never"]
/never/i.exec("Never, never pour salt in your eyes.");
//-> ["Never"]
You’ll notice the matches themselves are arrays, too The first item in this array is the
full match If there are any captures in the expression—indicated by parentheses—then
those submatches are also given in the order they occur Since we’re trying to figure out if
“never” is capitalized or not, let’s capture the first letter of the pattern:
C H A P T E R 8 ■ OT H E R H E L P F U L T H I N G S : U S E F U L M E T H O D S O N B U I LT- I N S
168
Trang 4/(n)ever/i.exec("Never, never pour salt in your eyes.");
//-> ["Never", "N"]
We’ll turn it into a function—one that decides on a proper replacement string for each
match
"Never, never pour salt in your eyes.".gsub(/(n)ever/i, function(match) {
if (match[1] === match[1].toUpperCase()) return "Always";
else return "always";
});
//-> "Always, always pour salt in your eyes."
only the first match of a given pattern in a string:
"Never, never pour salt in your eyes.".sub(/never/i, 'Always');
//-> "Always, never pour salt in your eyes."
And String#scanis used for executing a function against each match of a pattern:
// find all four-letter words in a phrase
var warning = "Never, never pour salt in your eyes.", fourLetterWords = [];
warning.scan(/\b\w{4}\b/, function(match) { fourLetterWords.push(match[0]); });
console.log("Four-letter words: " + fourLetterWords.join(', ') );
//-> "Four-letter words: pour, salt, your, eyes"
To review, all three of these methods let you search for a pattern in a string
There-fore, all three expect either a string or a regular expression as the first argument Two
function for every occurrence of a pattern
The strip Method
leading and trailing spaces from a string:
" foo ".strip(); //-> "foo"
Trang 5In the unpredictable browser environment, where whitespace fills every crack and
var a = "bar ", b = " bar";
a == b; //-> false
a.strip() == b.strip(); //-> true
The stripTags, escapeHTML, and unescapeHTML Methods
It’s frustrating to deal with HTML in string form, but it’s often necessary Many Prototype
place content into a page
It’s also important to write code that’s both defensive and secure Let’s look at an example:
<form id="blog_comment" action="/path/to/action/page">
<p>
<label for="comment_name">Name </label><br />
<input id="comment_name" name="comment_name" type="text" />
</p>
<p>
<label for="comment_text">Comment</label><br />
<textarea id="comment_text" name="comment_text"></textarea>
</p>
</form>
<div id="live_preview"></div>
Assume that this is a standard blog comment form We want to let the commenter
with each keystroke:
function updateLivePreview() {
var commentText = $('comment_text').value;
$('live_preview').update(commentText);
}
Event.observe(window, 'load', function() {
$('comment_text').observe('keyup', updateLivePreview);
});
C H A P T E R 8 ■ OT H E R H E L P F U L T H I N G S : U S E F U L M E T H O D S O N B U I LT- I N S
170
Trang 6Load this example in a browser, and you’ll see that this code behaves the way we
(Figure 8-1)
Figure 8-1.Live comment preview
But it’s not enough to test typical input We’ve also got to test how resilient it is by
feeding it unexpected input Sure enough, this code handles plain text deftly, but doesn’t
like HTML all that much (see Figure 8-2)