1. Trang chủ
  2. » Công Nghệ Thông Tin

Practical prototype and scipt.aculo.us part 32 doc

6 75 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 6
Dung lượng 87,04 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Our toStringmethod returned the first and last names of the player: var qb = new Quarterback"Andrew", "Dupont"; qb; //-> [Object]; qb + " just won the Heisman trophy."; //-> "Andrew Dupo

Trang 1

Advanced Replacement

Recall in the previous chapter how we created classes for football players, where each instance of a class was a specific player Each had properties like firstName,lastName, and

We also defined a custom toStringmethod, taking advantage of the fact that

JavaScript uses a method by that name whenever it needs to coerce an object into a string Our toStringmethod returned the first and last names of the player:

var qb = new Quarterback("Andrew", "Dupont");

qb; //-> [Object];

qb + " just won the Heisman trophy.";

//-> "Andrew Dupont just won the Heisman trophy."

Because concatenating (+) a string to another object involves automatic string coercion, our instance of Quarterbackknew how to represent itself in that context

inter-polating with has a special method called toTemplateReplacements, then the result of that method will be used to fill in the template string:

var blatantLie = new Template(

"#{position} #{firstName} #{lastName} just won the Heisman trophy.");

blatantLie.evaluate(qb);

//-> " Andrew Dupont just won the Heisman trophy."

// adding an instance method to the Quarterback class

Class.extend(Quarterback, {

toTemplateReplacements: function() {

return {

position: "QB",

firstName: this.firstName,

lastName: this.lastName

};

}

});

blatantLie.evaluate(qb);

//-> "QB Andrew Dupont just won the Heisman trophy."

Here, we’ve done a before-and-after comparison The first time we call

Trang 2

in the holes of the template string That instance has firstNameand lastNameproperties,

but it doesn’t have a positionproperty, so an empty string is used instead

When we add Quarterback#toTemplateReplacements, though, we’re supplying a

substi-tute object to use for interpolation So we’re able to specify properties above and beyond

those that already exist on the object In this case, we’re defining a positionproperty to

go into the evaluated string

The larger purpose of defining toTemplateReplacementsis the same as the purpose

as defining toString: it allows you to specify in one place how your object will behave in

a given context For user-defined classes, it also promotes encapsulation, one of those

hallowed OOP virtues

It’s all part of the theme that was established in Chapter 3: ensuring that objects

come with instructions for use Just like we rely on objects that mix in Enumerableto know

how to enumerate themselves, here we’re relying on objects to know how to represent

themselves in a Templatecontext

Bringing It Back to String#gsub

The versatility of JavaScript objects gives us a bonus way to use Template Remember that

an array is really just an object with numerals as keys, so Templateand String#interpolate

can be used with arrays as well:

var sample = new Template("The quick brown #{0} jumps over the lazy #{1}");

sample.evaluate(["fox", "dog"]);

//-> "The quick brown fox jumps over the lazy dog."

Items of an array respond to property lookups just like any other object

Finally, then, I can share an Easter egg of sorts—template strings like these can be

used in String#gsub:

var warning = "Never, never pour salt in your eyes."

warning.gsub(/(salt) in your (eyes)/, "#{2} in your #{1}");

//-> "Never, never pour eyes in your salt."

You may also recall that the first item in a match array is the entire string that

matches the pattern; any subsequent items are substrings that match specific captures in

the regular expression The preceding example, then, is shorthand for either of these:

Trang 3

warning.gsub(/(salt) in your (eyes)/, function(match) {

return match[2] + " in your " + match[1];

});

// or

warning.gsub(/(salt) in your (eyes)/, function(match) {

return "#{2} in your #{1}".interpolate(match);

});

OK, I take it back: maybe strings are more awesome than we realized.

Using JSON

Strings are the building blocks of high-level protocols like HTTP A client and a server communicate in plain text, which, while much less friendly than the rendered view of a browser, is nonetheless human-readable

Each time your browser requests an HTML file, it receives one gigantic string, which

it then converts into a tree of objects for rendering It converts between the two

accord-ing to the rules of HTML It can be said, then, that HTML is a serializer: it takes somethaccord-ing

inherently nonlinear and makes it linear for storage purposes

The interesting stuff is done at higher levels, with more complex data types But on

the Web, sooner or later, it all ends up as a string JSON (JavaScript Object Notation) is

simply a way to represent these complex structures as strings

What Does JSON Look Like?

Prototype likes to leverage the literal syntax for object creation, so code like this should

be nothing new to you:

var vitals = {

name: "Andrew Dupont",

cities: ["Austin", "New Orleans"],

age: 25

};

We can describe data structures in JavaScript with a minimum of syntactic cruft By comparison, let’s see what this data would look like in XML:

Trang 4

<name>Andrew Dupont</name>

<cities>

<city>Austin</city>

<city>New Orleans</city>

</city>

<age>25</age>

</vitals>

XML is verbose by design What if we don’t need its extra features? That’s where JSON

comes in

Why JSON?

There are a million different ways to exchange data between client and server; what’s so

special about JSON?

Very little, really It’s not magical; it’s simply the right tool for the job in

JavaScript-heavy web apps There are JSON libraries for all the common server-side languages: PHP,

Ruby, Python, Java, and many others It’s far simpler than XML, and thus far more useful

when you don’t need all of XML’s bells and whistles

We’ll revisit JSON in Part 2 of this book when we look into advanced topics in Ajax

But let’s familiarize ourselves with the basics right now

Serializing with Object.toJSON

The best way to learn about the structure of JSON is to try it out yourself Let’s create a

few different JavaScript data types and see how they look in JSON:

var str = "The Gettysburg Address";

var num = 1863;

var arr = ["dedicate", "consecrate", "hallow"];

var obj = {

name: "Abraham Lincoln",

location: "Gettysburg, PA",

length: 269

};

Trang 5

Object.toJSON(str); //-> '"The Gettysburg Address"'

Object.toJSON(num); //-> '1863

Object.toJSON(arr);

//-> '["dedicate", "consecrate", "hallow"]'

Object.toJSON(obj);

//> '{ "name": "Abraham Lincoln", "location": "Gettysburg, PA",

"length": 269 }'

These examples teach you several new things:

• The way items are represented in JSON is identical to how they’re represented in

JavaScript JSON conforms to the syntax and grammar of JavaScript

In other words, in each of these cases, the string representation of the data matches

the keyboard characters you’d type to describe them yourself.

JSON can serialize any JavaScript data type except for functions and regular expres-sions The Datetype gets half credit: there’s no literal notation for dates, so they’re

converted to a string representation

Unserializing with String#evalJSON

The ease of dealing with JSON in JavaScript should be obvious: since it’s valid code, it can simply be evaluated JavaScript includes an evalfunction that will evaluate a string as though it were code:

var data = eval('{ "name": "Abraham Lincoln", "location": "Gettysburg, PA",

"length": 269 }');

//-> [Object]

But there’s a problem It’s always dangerous to evaluate arbitrary code unless you know exactly where it’s coming from Prototype’s String#evalJSONwill evaluate a string as code, but it takes an optional Boolean; if true, it will make sure the given string is valid JSON—and therefore not a security risk

Trang 6

var str = '{ "name": "Abraham Lincoln", "location": "Gettysburg, PA",

"length": 269 }';

str.evalJSON(); //-> [Object]

// Ensuring it's valid JSON

str.evalJSON(true); //-> [Object]

// Now try it with invalid, malicious JSON

str = '{ "name": "Abraham Lincoln" }; doSomethingMalicious();'.evalJSON(true);

//-> SyntaxError: Badly formatted JSON string

Most of the time, you’ll be using JSON simply as a way to communicate with your

own server, so security won’t be an issue But if you happen to be handling JSON from a

third party, you must make sure it’s safe to use.

Overriding the Default Serialization

reporting some properties and ignoring all others:

// Just first name, last name, and points

Class.extend(Player, {

toJSON: function() {

return Object.toJSON({

firstName: this.firstName,

lastName: this.lastName

});

}

});

// But maybe subclasses should also report their position

Class.extend(Quarterback, {

toJSON: function() {

return Object.toJSON({

position: 'QB',

firstName: this.firstName,

lastName: this.lastName,

Ngày đăng: 03/07/2014, 01:20