Advanced ASP.NET AJAX Server Controls, For .NET Framework 3.5 (2009)

Advanced ASP.NET AJAX Server Controls, For .NET Framework 3.5 (2009)

(Parte 4 de 5)


PART I Client Code

1 Programming with JavaScript

ASWECOVEREDINTHEPREFACE, ASP.NET AJAX is composed of three distinct sections: the Microsoft AJAX Library, ASP.NET 2.0

AJAX, and the ASP.NET AJAX Control Toolkit. In this chapter, we focus on the programming language that powers the Microsoft AJAX Library, JavaScript.

We’re spending some time on JavaScript rather than jumping directly into programming with the Microsoft AJAX Library because successfully programming using the Microsoft AJAX Library requires a solid foundation of JavaScript, the language it was written in and extends. As much as the Library provides to ease client-side development and turn JavaScript programming into an object-oriented development experience ASP.NET developers can relate to, we still need rock-solid JavaScript skills when we program within it. Otherwise, we won’t be able to take full advantage of its abilities and won’t understand how to use it properly.

Because JavaScript is a full programming language, covering it completely requires a full book. If you want to master it completely, we recommendJavaScript: The Definitive Guideby David Flanagan and Pro JavaScript Techniquesby John Resig. Because this book is about ASP.NET AJAX and not JavaScript, however, we cannot cover every nook and cranny of the language. Instead, we try to tackle concepts that you might have glossed over in your day-to-day development. Topics we cover are functions as firstclass objects, primitive data types, objects, equality, variable scope, and function arguments.

From there, we transition into developing a few objects that act like a classic object-oriented system. We cover this because the Microsoft AJAX Library acts like a classic object-oriented system, and it’s important to understand the basics of how Microsoft created this system so that we can be prepared for and understand its programming model.

Generally JavaScript

JavaScript Introduction JavaScript can be separated into two categories: client-side JavaScript (CSJS) and server-side JavaScript (SSJS). SSJS is used infrequently when compared to its client-side sibling. Because we’re looking at client technologies, when we refer to JavaScript in this book we refer to CSJS.

JavaScript is actually the Mozilla Foundation implementation of the

ECMAScriptstandard, but the term is more commonly used to refer to all implementations of the ECMAScript standard rather than to the Mozilla Foundation-specific implementation. When we refer to JavaScript in this book, we are referring to the ECMAScript standard, not the Mozilla-specific implementation. Keep in mind, however, that different browsers have implemented the standard in moderately different ways.

Despite its name, JavaScript is completely unrelated to the Sun

Microsystem Java programming language. Netscape changed the language name from LiveScript to JavaScript as a co-marketing deal between Netscape and Sun when Java was bundled with the Netscape browser, back when Netscapewas the dominate browser. In retrospect, it is a horrible name that has been the source of confusion for many developers.

Language Attributes

Dynamically Typed In dynamically typed languages, the data types are not declared and are not known until execution time. This is in contrast to statically typed

Chapter 1:Programming with JavaScript4 languages, such as C# or Java, where data types are declared and known at compile type. Dynamically typed languages can lead to more flexible applications when compared to statically typed languages, but developers often prefer the clarity and error checking that declared and compiled data types provide in a statically typed language. The example in Listing 1.1 shows legal statements in JavaScript, a dynamically typed language, which would be illegal in a statically typed language.

Listing 1.1Dynamic Typing var x = 5; // set x to 5 x = "hello!"; // set x to 'hello!'

In JavaScript, this is perfectly legal because the type is associated to the value of the variable rather than the variable itself. In contrast, this is illegal in a statically typed language because the type is associated to the variableand the compiler wouldn’t allow xto change its associated type from an integer to a string.

Interpreted Like most scripting languages, JavaScript is interpreted rather than compiled. Its code is stored as text and interpreted into machine instructions and stored in memory as the program runs. This is in contrast to compiled languages, such as C# and Java, where the code is compiled into machine instructions or an intermediate form such as ILor bytecode in a discrete step before program execution begins.

Functions as First-Class Objects In JavaScript, Functionis a type of built-in object. It has a property that contains executable code and can be invoked using its name followed by parentheses, (). The Functionobject is important because it enables us to group code into a callable block. We actually use the Functiontype unknowingly whenever we declare a new function. Whenever the keyword functionis used, it actually creates a new object of type Functionpassing in the function’s body to Function’s constructor. Listing 1.2 demonstrates this concept. The two methods, newMethodandnewMethod2, are exactly the same thing (other than their names) once interpreted and executed by the JavaScript runtime.

Generall y Jav aScript 5

Listing 1.2 Creating Functions var newMethod = new Function("alert ('new method');"); newMethod(); // alerts "new method" function newMethod2() { alert ("new method"); } newMethod2(); // alerts "new method"

Because we can create an object of type Function, we can declare functions wherever we want without enclosing them inside another concept such as a class, as we normally do in class-based object-oriented programming languages. The ability to do this makes the function a first-class citizen (or object) of the language.

This idea has important ramifications. It means that functions act as the bounding construct of the language and displace what we might consider a normal object-oriented principle, classes. No keyword represents the common class idea found in most modern object-oriented programming languages such as Java or C#. (The classkeyword in JavaScript refers to a CSS class.) Rather, as we discuss in the “Object-Oriented JavaScript Programming” section later in this chapter, functions act as the boundary for new types.

An important aspect of JavaScript functions is that they are unique only by name, not by name plus arguments as in other languages. If we declare one function and then declare another function with the same name, the second function overwrites the first one.

Primitive Data Types JavaScript has three primitive data types: boolean,number, and string. It also has two special values: undefinedandnull. (We cover nulland undefinedlater in this section and explain the differences between undefinedthe value and undefinedthe type.) Everything else is a variation of the Objecttype, which we cover in detail in this chapter’s “Objects” section.

booleans Abooleanhas two possiblevalues: trueorfalse. booleans can be created by assigning true,false,1(indicating true), or 0(indicating false) to a variable, as shown in Listing 1.3.

Chapter 1:Programming with JavaScript6

Listing 1.3 Declaring boolean Variables var x = false; var y = true; var z = 1; alert (y === z); // alerts 'true'

Numbers Numbers are always stored as 64-bit values, similar to doubles in .NET. Because of this single numbertype, division between any two numbers can produce fractional results. The numbertype also contains a series of special values shown in Table 1.1. Anumber can be manipulated through normal mathematical and bitwise expressions, and normal order-of-operations precedence is applied (parentheses, exponents, multiplication, division, addition, and subtraction). If the current value has a decimal value and a bitwise expression is used, the number is first converted to a 32-bit integer using rounding, the bitwise expression is applied, and then the number is converted back to a 64-bit double.

Table 1.1Special Number Values

Constant Definition

Number.NaNorNanNot a number. Useful for determining whether a variable can be coerced into a Number type.

Number.InfinityorInfinityRepresents the greatest possible value, but has no numeric value.

Number.MAX_VALUELargest possible number represented within the 64 bits.

Number.MIN_VALUESmallest possible number represented within the 64 bits.

Number.POSITIVE_INFINITY Represents positive infinity. Number.Negative_INFINITY Represents negative infinity.

Generall y Jav aScript 7


Astring is a sequence of zero or more Unicode values used to represent text. They are immutable (modification produces a new string), and there is no separate character type that represents a string of length one.

Strings are created using quotation marks. They can be either single (') or double (") quotation marks, but they have to be paired properly. The forward slash (\) is used for escaping quotes and special characters within a string. Listing 1.4 demonstrates some patterns used to create strings.

Listing 1.4 Declaring String Variables var x = "Hello!"; var y = 'Hello Again!'; var z = 'Hello, I\'m Bob';

Table 1.2 shows the other special characters that use the forward slash to escape them.

Table 1.2Special Characters

Escape Sequence Output \'Single quote (‘)

\"Double quote (“)

\\Backslash (\)

\b Backspace

\tHorizontal tab

\nNew line character

\rCarriage return character

\fForm feed character

\dddOctal sequence (3 digits)

\xddHexadecimal sequence (2 hex digits)

\uddddUnicode sequence (4 hex digits)

Chapter 1:Programming with JavaScript8

Objects Besides variables that are primitive data types, every other variable in JavaScript is an object. Functions, dates, and Document Object Model (DOM) elements, among many others, are all objects. Objects are how we extend the language with our own types, write modular code, and generally make our code easier to understand. We use objects extensively throughout the rest of this book, and we discuss how to use them in a classic object-oriented system later in this chapter. For now, however, let’s go over some object basics.

Basics First, we can create new objects in two different ways. We can use the builtinObjecttype with the newkeyword, or we can use an object literal. An object literal is a string that defines the object and is begun with a left curly brace ({) and ended with a right curly brace (}). Listing 1.5 demonstrates using these two methods to create two new object instances.

Listing 1.5 Creating New Object Instances var myCar = new Object(); var myCar2 = { };

Strings 9

NOTEString Concatenation Is Expensive!

Any time you assign a string to a variable, memory is allocated from the heap to store that string. This occurs because strings are immutable. They cannot change after they have been assigned to a variable. Therefore, take care, where possible, to avoid concatenating strings. Certain techniques are available, which the Microsoft AJAX Library makes readily accessible through the Sys.StringBuildertype, to avoid string concatenations through the use of arrays to store string parts. We strongly suggest that if you want to write string concatenation code that performs well, use the Sys.StringBuilderclass just as you would on the server.

These objects already have a function available just because they’re objects. The toStringfunction is attached to the object’s prototype (we explain what a prototype is in a bit), and therefore it is subsequently available on all instances that inherit from Object, which is everything.

Besides having the toStringfunction, which would require an override to make it output anything interesting, these objects are a bit plain because they have no properties assigned. We can assign properties to an object using either the Object Literal notation or through a dot notation. Listing 1.6 shows both ways as we add the makeandmodelproperties to the two object instances we created in Listing 1.5.

Listing 1.6 Object Properties var myCar = new Object(); myCar.make = 'Ford'; myCar.model = 'Explorer'; var myCar2 = { make: "Ford", model: "Explorer" };

JavaScript stores an object’s propertiesusing an associative array, which is an array that is accessed by key rather than index. The dot notation that we used in Listing 1.6 is just another way of accessing the values in the associative array. We could have just as easily added the properties using array syntax. Listing 1.7 demonstrates this concept.

Listing 1.7 Object Properties as Associative Arrays var myCar = new Object(); myCar.make = 'Ford'; myCar["model"] = 'Explorer'; alert (myCar.make === myCar["make"]); // alerts true.

Chapter 1:Programming with JavaScript10

NOTE Associative Arrays

Associative arrays are a great way of accessing a property on an object by name. Whenever you’re tempted to use an evalstatement to access the property on an object, you can most likely access it by array position instead.

Because objects store their properties in an associative array, we can iterate over the properties using a for…inloop. Listing 1.8 demonstrates this concept as we iterate over the properties of our myCarobject.

Listing 1.8 Using a for…in Loop var myCar = new Object(); myCar.make = 'Ford'; myCar["model"] = 'Explorer'; myCar.year = 2003; myCar.mileage = 60000; var propValues; for (var propName in myCar) { propValues = propValues + " " + myCar[propName]; } alert (propValues); / alerts "Ford Explorer 2003 60000 ";

Just as we defined properties, we can define functions. Listing 1.9 adds theprintfunction to our myCarobject.

Listing 1.9 Object Functions myCar.print = function() { alert (this.make + " " + this.model); }; myCar.print(); // alerts 'Ford Explorer'

We could have done all of this using the Object Literal notation, too. Listing 1.10 shows how to create the same object using Object Literal notation.

Listing 1.10Object Literal Notation var myOtherCar = { make: "Ford", model: "Explorer", year: 2003, mileage: 60000 print: function() { alert (this.make + " " + this.model); } myOtherCar.print // alerts 'Ford Explorer'

Strings 1

Adding properties and functions to an existing object is useful in many cases, but has serious drawbacks because those properties and functions are added only to that particular instance. If we wanted to create another object that has the same properties and functions, we would have to re-add them to the new object instance. Fortunately, JavaScript provides other ways of attaching properties and functions to an object so that they have to be defined only one time. We cover this mechanism in the “Object-Oriented JavaScript Programming” section of this chapter.

Chapter 1:Programming with JavaScript12

NOTE Expando Properties

Adding properties and functionsto an object in the manner we just discussed is called adding an Expando property. Expando properties tend to be slow performing when compared to custom objects; so although they have some useful purposes, their use should be limited to those situations where you have no choice but to use them. Instead, you should use the custom object technique we cover in the “Object- Oriented JavaScript Programming” section of this chapter.

(Parte 4 de 5)