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

JavaScript Bible, Gold Edition part 122 pdf

10 153 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 10
Dung lượng 93,44 KB

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

Nội dung

Unlike the catchblock, a finallyblock does not receive an error object as a parameter, so it operates very much in the dark about what transpires inside the tryblock.. In the first, the

Trang 1

The single catchblock in Listing 39-7 executes only if one of the statements in the tryblock throws an exception The exceptions may be not only one of the four specific ones named in the catchblock but also syntax or other errors that could occur inside the tryblock That’s why you have a last-ditch case to handle truly unexpected errors Your job as scripter is to not only anticipate errors but also to provide clean ways for the exceptions to be handled, whether they be through judi-ciously worded alert dialog boxes or perhaps even some self-repair For example, in the case of the invalid character error for createElement(), your script may attempt to salvage the data passed to the attachToEnd()function and reinvoke the method passing theNodevalue as-is and the repaired value originally passed to

newTag If your repairs were successful, the tryblock would execute without error and carry on with the user’s being completely unaware that a nasty problem had been averted

A finallyblock contains code that always executes after a tryblock, whether

or not the tryblock succeeds without throwing an error Unlike the catchblock, a

finallyblock does not receive an error object as a parameter, so it operates very much in the dark about what transpires inside the tryblock If you include both

catchand finallyblocks after a tryblock, the execution path depends on whether an exception is thrown If no exception is thrown, the finallyblock exe-cutes after the last statement of the tryblock runs But if the tryblock throws an exception, program execution runs first to the catchblock After all processing within the catchblock finishes, the finallyblock executes In development envi-ronments that give programmers complete control over resources, such as memory allocation, a finallyblock may be used to delete some temporary items generated

in the tryblock, whether or not an exception occurs in the tryblock Currently, JavaScript has less need for that kind of maintenance, but you should be aware of the program execution possibilities of the finallyblock in the try-catch-finally

context

Real-life exceptions

The example shown in Listing 39-6 is a bit idealized The listing assumes that the browser dutifully reports every W3C DOM exception precisely as defined in the for-mal specification Unfortunately, that’s not how it is (yet) in browsers through IE5.5 and NN6 Both browsers implement additional error naming conventions and layers between actual DOM exceptions and what gets reported with the error object at the time of the exception

If you think these discrepancies make cross-browser exception handling difficult, you’re right Even simple errors are reported differently among the two major browser brands and the W3C DOM specification Until the browsers exhibit a greater unanimity in exception reporting, the smoothest development road will be for those scripters who have the luxury of writing for one of the browser platforms, such as IE5 for Windows or NN6

That said, however, one aspect of exception handling can still be used in both IE5+ and NN6 You can take advantage of try-catchconstructions to throw your own exceptions — a practice that is quite common in advanced programming environments

try-catch-finally

Trang 2

Throwing Exceptions

The last exception handling keyword not covered yet —throw— makes it

possi-ble to utilize exception handling facilities for your own management of processes,

such as data entry validation At any point inside a tryblock, you can manually

throw an exception that gets picked up by the associated catchblock The details

of the specific exception are up to you

Syntax for the throwstatement is as follows:

throw value

The value you throw can be of any type, but good practice suggests that the

value be an error object (described more fully later in this chapter) Whatever

value you throw is assigned to the parameter of the catchblock Look at the

fol-lowing two examples In the first, the value is a string message; in the second, the

value is an error object

Listing 39-8 presents one input text box for a number between 1 and 5 Clicking a

button looks up a corresponding letter in an array and displays the letter in a

sec-ond text box The lookup script has two simple data validation routines to make

sure the entry is a number and is in the desired range Error checking here is done

manually by script If either of the error conditions occurs, throwstatements force

execution to jump to the catchblock The catchblock assigns the incoming

stringparameter to the variable e The design here assumes that the message

being passed is text for an alert dialog box Not only does a single catchblock take

care of both error conditions (and conceivably any others to be added later), but

the catchblock runs within the same variable scope as the function, so that it can

use the reference to the input text box to focus and select the input text if there is

an error

Listing 39-8: Throwing String Exceptions

<HTML>

<HEAD>

<TITLE>Throwing a String Exception</TITLE>

<SCRIPT LANGUAGE=”JavaScript”>

var letters = new Array(“A”,”B”,”C”,”D”,”E”)

function getLetter(fld) {

try {

var inp = parseInt(fld.value, 10)

if (isNaN(inp)) {

throw “Entry was not a number.”

}

if (inp < 1 || inp > 5) {

throw “Enter only 1 through 5.”

}

fld.form.output.value = letters[inp]

}

catch (e) {

alert(e)

fld.form.output.value = “”

Trang 3

Listing 39-8 (continued)

fld.focus() fld.select() }

}

</SCRIPT>

</HEAD>

<BODY>

<H1>Throwing a String Exception</H1>

<HR>

<FORM>

Enter a number from 1 to 5:

<INPUT TYPE=”text” NAME=”input” SIZE=5>

<INPUT TYPE=”button” VALUE=”Get Letter” onClick=getLetter(this.form.input)> Matching Letter is:<INPUT TYPE=”text” NAME=”output” SIZE=5>

</FORM>

</BODY>

</HTML>

The flaw with Listing 39-8 is that if some other kind of exception were thrown inside the tryblock, the value passed to the catchblock would be an error object, not a string The alert dialog box displayed to the user would be meaningless Therefore, it is better to be uniform in your throw-catchconstructions and pass an error object

Listing 39-9 is an updated version of Listing 39-8, demonstrating how to create an error object that gets sent to the catchblock via throwstatements The one glitch

in generating an error object comes in IE5 and IE5.5 The ECMA-262 standard allows

a script statement to set the messageproperty of an error object to directly by passing a string as the parameter to the new Error()constructor This is how NN6 works But the error object in IE5 does not have the messageproperty at all, and in IE5.5, the parameter is not assigned to the messageproperty Therefore, Listing 39-9 contains a separate utility function (getErrorObj()) that fills the gap when an error object does not have the messageproperty to begin with or doesn’t have the property set automatically If a future version of IE adopts the ECMA standard way, then the extra branch is avoided, just as it is for NN6

Listing 39-9: Throwing an Error Object Exception

<HTML>

<HEAD>

<TITLE>Throwing an Error Object Exception</TITLE>

<SCRIPT LANGUAGE=”JavaScript”>

var letters = new Array(“A”,”B”,”C”,”D”,”E”) function getErrorObj(msg) {

var err = new Error(msg) // take care of IE5/5.5

if (!err.message) {

throw

Trang 4

err.message = msg

}

return err

}

function getLetter(fld) {

try {

var inp = parseInt(fld.value, 10)

if (isNaN(inp)) {

throw getErrorObj(“Entry was not a number.”)

}

if (inp < 1 || inp > 5) {

throw getErrorObj(“Enter only 1 through 5.”)

}

fld.form.output.value = letters[inp]

}

catch (e) {

alert(e.message)

fld.form.output.value = “”

fld.focus()

fld.select()

}

}

</SCRIPT>

</HEAD>

<BODY>

<H1>Throwing an Error Object Exception</H1>

<HR>

<FORM>

Enter a number from 1 to 5:

<INPUT TYPE=”text” NAME=”input” SIZE=5>

<INPUT TYPE=”button” VALUE=”Get Letter” onClick=getLetter(this.form.input)>

Matching Letter is:<INPUT TYPE=”text” NAME=”output” SIZE=5>

</FORM>

</BODY>

</HTML>

The only difference to the catchblock is that it now reads the messageproperty

of the incoming error object This means that if some other exception is thrown

inside the tryblock, the browser-generated message will be displayed in the alert

dialog box

In truth, however, the job really isn’t complete In all likelihood, if a

browser-generated exception is thrown, the message in the alert dialog box won’t mean

much to the user The error message will probably be some kind of syntax or type

error — the kind of meaningless error message you often get from your favorite

operating system A better design is to branch the catchblock so that “intentional”

exceptions thrown by your code are handled through the alert dialog box messages

you’ve put there, but other types are treated differently To accomplish this, you

can take over one of the other properties of the error object —name— so that your

catchblock treats your custom messages separately

Trang 5

In Listing 39-10, the getErrorObj()function adds a custom value to the name

property of the newly created error object The name you assign can be any name, but you want to avoid exception names used by JavaScript or the DOM Even if you don’t know what all of those are, you can probably conjure up a suitably unique name for your error Down in the catchblock, a switchconstruction branches to treat the two classes of errors differently Notice that because IE5’s error object does not have a nameproperty, the switchexpression (e.name) evaluates to

undefined, which forces the defaultcase to execute whenever a native exception

is thrown (and you have to be careful about which error object properties you use

in the defaultcase statements) In this simplified example, about the only possi-ble propossi-blem other than the ones being trapped for explicitly in the tryblock would

be some corruption to the page during downloading Therefore, for this example, the branch for all other errors simply asks that the user reload the page and try again The point is, however, that you can have as many classifications of custom and system errors as you want and handle them in a single catch block accordingly

Listing 39-10: A Custom Object Exception

<HTML>

<HEAD>

<TITLE>Throwing a Custom Error Object Exception</TITLE>

<SCRIPT LANGUAGE=”JavaScript”>

var letters = new Array(“A”,”B”,”C”,”D”,”E”) function getErrorObj(msg) {

var err = new Error(msg) // take care of IE5/5.5

if (!err.message) { err.message = msg }

err.name = “MY_ERROR”

return err }

function getLetter(fld) { try {

var inp = parseInt(fld.value, 10)

if (isNaN(inp)) { throw getErrorObj(“Entry was not a number.”) }

if (inp < 1 || inp > 5) { throw getErrorObj(“Enter only 1 through 5.”) }

fld.form.output.value = letters[inp]

} catch (e) { switch (e.name) { case “MY_ERROR” : alert(e.message) fld.form.output.value = “”

fld.focus() fld.select()

throw

Trang 6

break default : alert(“Reload the page and try again.”) }

}

}

</SCRIPT>

</HEAD>

<BODY>

<H1>Throwing a Custom Error Object Exception</H1>

<HR>

<FORM>

Enter a number from 1 to 5:

<INPUT TYPE=”text” NAME=”input” SIZE=5>

<INPUT TYPE=”button” VALUE=”Get Letter” onClick=getLetter(this.form.input)>

Matching Letter is:<INPUT TYPE=”text” NAME=”output” SIZE=5>

</FORM>

</BODY>

</HTML>

If you want to see how the alternative branch of Listing 39-10 looks, copy the

list-ing file from the CD-ROM to your hard disk and modify the last line of the tryblock

so that one of the letters is dropped from the name of the array:

fld.form.output.value = letter[inp]

This may simulate the faulty loading of the page If you enter one of the allowable

values, the reload alert appears, rather than the actual message of the error object:

letter is undefined Your users will thank you

All that’s left now on this subject are the details on the error object

Error Object

Properties Methods

errorObject.constructor

errorObject.description

errorObject.filename

errorObject.lineNumber

errorObject.message

errorObject.name

errorObject.number

Trang 7

Creating an error object:

var myError = new Error(“message”) var myError = Error(“message”)

Accessing static Errorobject property:

Error.property

Accessing error object properties and methods:

errorObject.property | method([parameters])

About this object

An error object instance is created whenever an exception is thrown or when you invoke either of the constructor formats for creating an error object Properties

of the error object instance contain information about the nature of the error so that catchblocks can inspect the error and process error handling accordingly IE5 implemented an error object in advance of the ECMA-262 formal error object, and the IE5 version ends up having its own set of properties that are not part of the ECMA standard Those proprietary properties are still part of IE5.5, which includes the ECMA properties as well NN6, on the other hand, starts with the ECMA proper-ties and adds two proprietary properproper-ties of its own The browser uses these addi-tional properties in its own script error reporting The unfortunate bottom line for cross-browser developers is that no properties in common among all browsers sup-port the error object However, two common denominators (nameand message) are between IE5.5 and NN6

As described earlier in this chapter, you are encouraged to create an error object whenever you use the throwstatement for your own error control See the discus-sion surrounding Listing 39-9 about handling missing properties in IE

Properties

constructor

See string.constructor(Chapter 34)

description

errorObject.description

Trang 8

The descriptionproperty contains a descriptive string that provides some

level of detail about the error For errors thrown by the browser, the description is

the same text that appears in the script error dialog box in IE Although this

prop-erty continues to be supported, the messageproperty in IE5.5 and NN6 is preferred

Related Items:messageproperty

fileName

lineNumber

The NN6 browser uses the fileNameand lineNumberproperties of an error

object for its own internal script error processing — these values appear as part of

the error messages that are listed in the JavaScript Console The fileNameis the

URL of the document causing the error; the lineNumberis the source code line

number of the statement that threw the exception These properties are exposed to

JavaScript, as well, so that your error processing may use this information if it is

meaningful to your application

Both of these properties (along with the messageproperty) have been in the

Navigator vernacular since NN3 See the discussion of the window.errorproperty

in Chapter 16 for further ideas on how to use this information for bug reporting

from users

Related Items:window.errorproperty

message

The messageproperty contains a descriptive string that provides some level of

detail about the error For errors thrown by the browser, the message is the same

text that appears in the script error dialog box in IE and the JavaScript Console in

NN6 By and large, these messages are more meaningful to scripters than to users

Unfortunately, there are no standards for the wording of a message for a given error

Therefore, it is hazardous at best to use the message content in a catchblock as a

means of branching to handle particular kinds of errors You may get by with this

approach if you are developing for a single browser platform, but you have no

assurances that the text of a message for a particular exception may not change in

future browser versions

Trang 9

Custom messages for errors that your code explicitly throws can be in user-friendly language if you intend to display such messages to users See Listings 39-8 through 39-10 for examples of this usage

Related Items: description property.

name

The nameproperty generally contains a word that identifies the type of error that has been thrown The most general kind of error (and the one that is created via the new Error()constructor) has a name Error But JavaScript errors can be

of several varieties: EvalError, RangeError, ReferenceError, SyntaxError,

TypeError, and URIError Some of these error types are not necessarily intended for exposure to scripters (they’re used primarily in the inner workings of the JavaScript engine), but some browsers do expose them Unfortunately, there are some discrepancies as to the specific name supplied to this property for script errors

When JavaScript is being used in a browser environment that employs the W3C DOM, some DOM exception types are returned via the nameproperty But browsers frequently insert their own error types for this property, and, as is common in this department, little uniformity exists among browser brands

For custom exceptions that your code explicitly throws, you can assign names as you want As shown in Listings 39-9 and 39-10, this information can assist a catch

block in handling multiple categories of errors

Related Items:messageproperty

number

IE5+ assigns unique numbers to each error description or message The number

property, however, is problematical While Microsoft documents a sequence of syn-tax and runtime errors and their numbers, in practice, IE browsers do not report the numbers shown in Microsoft’s own documentation This is unfortunate, because the number can be a language-independent way of branching catchblock code based on the error number, rather than the description or message And,

errorObject.number

Trang 10

because the numberproperty was born at the same time as the description

prop-erty (now superseded by the messageproperty), it is unknown how reliable the

number values (if you can figure them out) will be going forward

Related Items:descriptionproperty

Methods

toString()

Returns: String (see text).

The toString()method for an error object should return a string description of

the error In IE5 and 5.5, however, the method returns a reference to the very same

error object In NN6, the method returns the messageproperty string, preceded by

the string Error:(with a space after the colon) Most typically, if you want to

retrieve a human-readable expression of an error object, read its message(or, in

IE5, description) property

Related Items:messageproperty

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