ASP.NET AJAX Programmer’s Reference - Chapter 4 doc

54 429 0
ASP.NET AJAX Programmer’s Reference - Chapter 4 doc

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

JavaScript Object-Oriented Programming and Type Reflection Extensions The .NET Framework comes with the following two important programming capabilities: ❑ Fully fledged typing and type reflection capabilities, allowing you to perform runtime-type inspections, discoveries, invocations, instantiations, and the like ❑ Fully fledged object-oriented capabilities, allowing you to take full advantage of all the well-known benefits of object-oriented programming (OOP) such as classes, interfaces, inheritance, and the like Because the main goal of the ASP.NET AJAX client-side framework is to emulate the ASP.NET and .NET Frameworks as much as possible, the ASP.NET AJAX client-side framework comes with a set of extensions — known as the ASP.NET AJAX OOP and type reflection extensions — that add .NET- like OOP and type reflection capabilities to JavaScript as much as possible. You’ve already seen some reflection capabilities in Chapter 2 where the ASP.NET AJAX client-side Framework extends the JavaScript Object type to add support for the getType and getTypeName methods. The .NET Framework comes with an important class named Type that provides most of the reflec- tion capabilities of the Framework. Following the same pattern, the ASP.NET AJAX client-side framework introduces a type named Type , which provides both OOP and type reflection capabili- ties, which I’ll discuss in this chapter. First, I’ll examine the JavaScript technologies that the ASP.NET AJAX OOP and type reflection extensions use under the hood to extend JavaScript to add OOP and type reflection support. This examination will put you in a much better position to understand and to use the ASP.NET AJAX client-side framework. c04.indd 77c04.indd 77 8/20/07 6:00:31 PM8/20/07 6:00:31 PM Chapter 4: JavaScript Object-Oriented Programming 78 JavaScript Functions Every JavaScript function is an instance of a JavaScript type named Function and supports the follow- ing properties: ❑ arguments : This property contains the parameters of a JavaScript function, which also includes the parameters that the original definition of the function does not contain. You can use this property to access the parameters of a function within the body of the function. As the following code shows, you can even define a function without any parameters and use the arguments property to access the parameters. However, this is not a recommended practice. function MyFunction() { for (var i = 0; i<arguments.length; i++) alert (arguments[i]); } window.onload = function() { MyFunction(‘info1’); MyFunction(‘info1’,’info2’); } ❑ constructor : The constructor property references the function or constructor that was invoked to create an object. For example, if you run the following code, the alert will show function Function () { [ native code ] } : <%@ Page Language=”C#” %> <html xmlns=”http://www.w3.org/1999/xhtml”> <head runat=”server”> <title>Untitled Page</title> <script language=”JavaScript” type=”text/javascript”> function MyFunction() { // Body of the function goes here } window.onload = function() { alert(MyFunction.constructor); } </script> </head> <body> <form id=”form1” runat=”server”> </form> </body> </html> ❑ prototype : The prototype property allows you to extend the functionality of a type to add sup- port for new instance properties and methods. JavaScript guarantees that all instances of the type will automatically inherit these new properties and methods. As you’ll see later, the ASP.NET AJAX client-side framework makes extensive use of this property to add OOP support to JavaScript. c04.indd 78c04.indd 78 8/20/07 6:00:31 PM8/20/07 6:00:31 PM Chapter 4: JavaScript Object-Oriented Programming 79 Every JavaScript function also supports two methods, call and apply , that you can use to invoke a function object. Using these methods to invoke a function may sound redundant because you can invoke a function by simply naming it. For example, you can invoke the MyFunction JavaScript function defined in the previous code fragment by simply calling MyFunction(); . Why would anyone then call MyFunction.call() to invoke the function when you can directly call the function itself? The call and apply methods enable you to specify the this value used inside a JavaScript function. As you can see, JavaScript enables you to specify not only the parameters passed into a JavaScript function but also the this value. As such, the first parameter of the call and apply methods references a JavaScript object, which is used to set this value. Note that this JavaScript object does note have to own the JavaScript function on which the call or apply method is invoked. As you’ll see later, the ASP.NET AJAX client-side framework uses this feature when it’s adding OOP support to JavaScript. Based on the fact that both the call and apply methods do the same thing — that is, invoke their asso- ciated method — you may be wondering why there are two methods. The main difference between these two methods is in how the parameters of their associated JavaScript functions are passed into these two methods. If your parameters are already loaded into an array, you can call the apply method and pass the array directly to this method. Otherwise, you can call the call method, passing the parameters as a list of comma-separated items. JavaScript Classes JavaScript is inherently an object-based programming language, not an object-oriented programming language. As such, it has limited OOP support, which is discussed in this section. There is no JavaScript keyword equivalent to the C# or VB.NET class keyword. The constructor of a JavaScript class also defines the class itself. Listing 4-1 presents an example of a JavaScript class named Employee . Listing 4-1: A JavaScript Class <%@ Page Language=”C#” %> <html xmlns=”http://www.w3.org/1999/xhtml”> <head runat=”server”> <title>Untitled Page</title> <script language=”JavaScript” type=”text/javascript”> function Employee (firstName, lastName) { this._firstName = firstName; this._lastName = lastName; } Employee.prototype = { get_firstName : function () {return this._firstName;}, set_firstName : function (value) {this._firstName = value;}, get_lastName : function() {return this._lastName;}, set_lastName : function (value) {this._lastName = value;} } (continued) c04.indd 79c04.indd 79 8/20/07 6:00:32 PM8/20/07 6:00:32 PM Chapter 4: JavaScript Object-Oriented Programming 80 Listing 4-1: (continued) window.onload = function() { var e = new Employee (“Shahram”, “Khosravi”); alert(e.get_firstName()); e.set_firstName(“Shahram1”); alert(e.get_firstName()); } </script> </head> <body> <form id=”form1” runat=”server”> </form> </body> </html> Type As mentioned earlier, the ASP.NET AJAX client-side framework introduces a new type or class named Type . Let’s take a look under the hood to see what the Type class is: window.Type = Function; As you can see, Type is basically a new alias for the Function class. This aliasing is done because “Type” makes more sense in the context of the .NET Framework. Keep in mind that the main goal of ASP.NET AJAX is to make the client-side framework act like the .NET Framework as much as possible. Aliasing Function to Type is just a simple first step toward this goal. The next step is to extend the Type (formerly known as Function ) class to add support for new methods and properties that will help make the client-side programming more like server-side .NET programming. As discussed previously, Type (or Function ) features a property named prototype . The JavaScript engine guarantees that every instance of Type automatically inherits every method and property assigned to the prototype property. This means that every JavaScript function will automatically inherit or pick up every method and property assigned to the prototype property of the Type or Function class. Because the constructor of every JavaScript class, including your own custom classes such as Employee , is nothing but a JavaScript function, this also means that every JavaScript class, including your own custom classes, will automatically inherit every method and property assigned to the prototype property of the Type or Function class. Next, you’ll learn how the ASP.NET AJAX client-side framework takes full advantage of this powerful feature of JavaScript to extend Type to add support for common OOP features such as namespaces, classes, inheritance, interfaces, and the like. Each of the following sections covers one of the new meth- ods or properties that the ASP.NET AJAX client-side framework has added to Type (or Function ). Each section consists of three parts. The first part describes what the method does. The second part presents an example where the method is used. The third part looks under the hood to show you how the method is implemented internally. Knowing the internals of these methods and properties will put you in a much better position to understand and to extend the ASP.NET AJAX client-side framework. c04.indd 80c04.indd 80 8/20/07 6:00:32 PM8/20/07 6:00:32 PM Chapter 4: JavaScript Object-Oriented Programming 81 register Class The ASP.NET AJAX client-side framework extends the functionality of Type to add support for a new method named registerClass . As the name implies, this method registers a specified class with the ASP.NET AJAX client-side framework. To add a new class to the ASP.NET AJAX client-side framework, you first need to implement the class. For example, the following code implements a class named Employee : Employee = function (firstName, lastName) { this_firstName = firstName; this_lastName = lastName; } Employee.prototype = { get_firstName : function () {return this._firstName;}, set_firstName : function (value) {this._firstName = value;}, get_lastName : function() {return this._lastName;}, set_lastName : function (value) {this._lastName = value;} } Then, call the registerClass function of the Employee class to register your new class with the ASP.NET AJAX client-side framework, as follows: Employee.registerClass(“Employee”); Listing 4-2 presents a page that defines, registers, and uses the new Employee class. Listing 4-2: Registering the Employee Class <%@ Page Language=”C#” %> <html xmlns=”http://www.w3.org/1999/xhtml”> <head id=”Head1” runat=”server”> <title>Untitled Page</title> </head> <body> <form id=”form1” runat=”server”> <asp:ScriptManager runat=”server” ID=”ScriptManager1” /> <script language=”JavaScript” type=”text/javascript”> Employee = function (firstName, lastName) { this._firstName = firstName; this._lastName = lastName; } (continued) c04.indd 81c04.indd 81 8/20/07 6:00:33 PM8/20/07 6:00:33 PM Chapter 4: JavaScript Object-Oriented Programming 82 Listing 4-2 (continued) Employee.prototype = { get_firstName : function () {return this._firstName;}, set_firstName : function (value) {this._firstName = value;}, get_lastName : function() {return this._lastName;}, set_lastName : function (value) {this._lastName = value;} } Employee.registerClass(“Employee”); var e = new Employee (“Shahram”, “Khosravi”); alert(e.get_firstName()); e.set_firstName(“Shahram1”); alert(e.get_firstName()); </script> </form> </body> </html> The following line of code seems to suggest that the Employee class has a method named registerClass : Employee.registerClass(“Employee”); However, as Listing 4-2 shows, the Employee class does not contain this method. To understand how this is possible, you need to look at the internal implementation of the registerClass method shown in Listing 4-3 . As this code listing shows, the registerClass is assigned to the prototype property of the Type or Function class. As discussed before, every JavaScript class, including your own custom classes, automatically inherits any method or property assigned to the prototype property of Type . Listing 4-3: The Portion of the Internal Implementation of the register Class Function Type.prototype.registerClass = function(c, b, d) { . . . this.prototype.constructor = this; this.__typeName = c; this.__class = true; . . . if(!window.__classes) window.__classes = {}; window.__classes[c.toUpperCase()] = this; . . . return this; }; Note that Listing 4-3 presents a portion of the internal implementation of the registerClass function. You’ll see the rest of the implementation of this function in the following sections. Also notice that c04.indd 82c04.indd 82 8/20/07 6:00:33 PM8/20/07 6:00:33 PM Chapter 4: JavaScript Object-Oriented Programming 83 registerClass takes three arguments. The second and third arguments are discussed later. As Listing 4-3 shows, the registerClass method takes these actions: 1. It assigns its first parameter to an internal field named __typeName : this.__typeName = c; As Listing 4-2 shows, this parameter contains the name of the class being registered — for example, “Employee” . 2. It sets an internal Boolean field named __class to true to specify that the entity being registered is a class: this.__class = true; 3. It instantiates a global object named _classes , if it hasn’t already been instantiated: if(!window.__classes) window.__classes = {}; 4. It uses the name of the class as an index to store the current class in the _classes object: window.__classes[c.toUpperCase()] = this; This means that the ASP.NET AJAX client-side framework maintains an internal object that contains all the classes registered with the framework. This allows you to perform runtime class reflection queries, similar to .NET class reflection queries. This also means that every class registered with the ASP.NET AJAX client-side framework maintains metadata information, such as the type name, in its internal fields, such as _typeName . This enables you to perform runtime object reflections similar to .NET object reflections on registered classes. You’ll see an example of this reflection in the next section. get Name The getName method returns the name of the specified type, as shown in the following example. This is a simple example of the reflection capabilities of the ASP.NET AJAX client-side framework. <%@ Page Language=”C#” %> <html xmlns=”http://www.w3.org/1999/xhtml”> <head id=”Head1” runat=”server”> <title>Untitled Page</title> </head> <body> <form id=”form1” runat=”server”> <asp:ScriptManager runat=”server” ID=”ScriptManager1” /> <script language=”JavaScript” type=”text/javascript”> (continued) c04.indd 83c04.indd 83 8/20/07 6:00:33 PM8/20/07 6:00:33 PM Chapter 4: JavaScript Object-Oriented Programming 84 Employee = function (firstName, lastName) { this_firstName = firstName; this._lastName = lastName; } Employee.prototype = { get_firstName : function () {return this._firstName;}, set_firstName : function (value) {this._firstName = value;}, get_lastName : function() {return this._lastName;}, set_lastName : function (value) {this._lastName = value;} } Employee.registerClass(“Employee”); alert(Employee.getName()); </script> </form> </body> </html> Once again, note that the getName method is called directly on the Employee class, implying that this class contains this method. As the following code shows, this is possible because the getName method is assigned to the prototype property of Type : Type.prototype.getName = function() { return typeof this.__typeName === “undefined” ? “” : this.__typeName; }; Notice that the getName function simply returns the value of the __typeName field discussed previously. is Class The isClass method is a static method of the Type class, which means that you must call this method directly on the Type itself. This method returns a Boolean value that specifies whether the parameter passed into it is a class. For example, the call into the isClass function in the boldfaced portion of the following code listing returns true, because Employee is registered as a class: <%@ Page Language=”C#” %> <html xmlns=”http://www.w3.org/1999/xhtml”> <head id=”Head1” runat=”server”> <title>Untitled Page</title> </head> <body> <form id=”form1” runat=”server”> <asp:ScriptManager runat=”server” ID=”ScriptManager1” /> <script language=”JavaScript” type=”text/javascript”> c04.indd 84c04.indd 84 8/20/07 6:00:34 PM8/20/07 6:00:34 PM Chapter 4: JavaScript Object-Oriented Programming 85 Employee = function (firstName, lastName) { this._firstName = firstName; this._lastName = lastName; } Employee.prototype = { get_firstName : function () {return this._firstName;}, set_firstName : function (value) {this._firstName = value;}, get_lastName : function() {return this._lastName;}, set_lastName : function (value) {this._lastName = value;} } Employee.registerClass(“Employee”); alert(Type.isClass(Employee)); </script> </form> </body> </html> As the following code shows, the isClass method is a static method because it’s not defined on the prototype property. Note that this method simply returns the value of the _class private field dis- cussed in Listing 4-3 . The isClass method is yet another example of the ASP.NET AJAX client-side framework’s type reflection capabilities. Type.isClass = function(a) { if(typeof a === “undefined” || a === null) return false; return !!a.__class; }; register Namespace The idea of a namespace is one of the fundamental OOP concepts, but JavaScript does not support namespaces. The ASP.NET AJAX client-side framework extends the functionality of Type to add support for a static method named registerNamespace that makes it possible to define namespaces in JavaScript. Because this method is static, you must call it directly on the Type itself. Here is an example: <%@ Page Language=”C#” %> <html xmlns=”http://www.w3.org/1999/xhtml”> <head id=”Head1” runat=”server”> <title>Untitled Page</title> </head> <body> <form id=”form1” runat=”server”> <asp:ScriptManager runat=”server” ID=”ScriptManager1” /> <script language=”JavaScript” type=”text/javascript”> Type.registerNamespace(“MyNamespace”); (continued) c04.indd 85c04.indd 85 8/20/07 6:00:34 PM8/20/07 6:00:34 PM Chapter 4: JavaScript Object-Oriented Programming 86 MyNamespace.Employee = function (firstName, lastName) { this._firstName = firstName; this._lastName = lastName; } MyNamespace.Employee.prototype = { get_firstName : function () {return this._firstName;}, set_firstName : function (value) {this._firstName = value;}, get_lastName : function() {return this._lastName;}, set_lastName : function (value) {this._lastName = value;} } MyNamespace.Employee.registerClass(“MyNamespace.Employee”); alert(Type.isClass(MyNamespace.Employee)); </script> </form> </body> </html> This example first registers a namespace named MyNamespace : Type.registerNamespace (“MyNamespace”); Then it defines a class named Employee that belongs to this namespace: MyNamespace.Employee = function (firstName, lastName) { this._firstName = firstName; this._lastName = lastName; } MyNamespace.Employee.prototype = { get_firstName : function () {return this._firstName;}, set_firstName : function (value) {this._firstName = value;}, get_lastName : function() {return this._lastName;}, set_lastName : function (value) {this._lastName = value;} } Finally, it registers the class with the ASP.NET AJAX client-side framework: MyNamespace.Employee.registerClass(“MyNamespace.Employee”); Note that the namespace of a class is part of the name of the class. Listing 4-4 presents the internal implementation of the registerNamespace method. As the first line of code shows, the ASP.NET AJAX client-side framework adds a new global array named _rootNamespaces to the window object. As you’ll see shortly, the registerNamespace method adds the global namespace being registered to this global array. In other words, this global array contains all the global namespaces registered with the ASP.NET AJAX client-side framework. c04.indd 86c04.indd 86 8/20/07 6:00:34 PM8/20/07 6:00:34 PM [...]... 1 04 c 04. indd 1 04 8/20/07 6:00 :40 PM Chapter 4: JavaScript Object-Oriented Programming The callBaseMethod method in the ASP.NET AJAX client-side framework allows a subclass’s implementation of a method to call its base class’s implementation This is yet another step that the ASP.NET AJAX client-side framework takes to emulate the NET Framework To help you understand how this works in the ASP.NET AJAX. .. its base class implementation If you run Listing 4- 2 0, you get the pop-up message shown in Figure 4- 3 Notice that the information displayed in this message contains the department information in addition to the first name, last name, and employee ID Figure 4- 3 109 c 04. indd 109 8/20/07 6:00 :42 PM Chapter 4: JavaScript Object-Oriented Programming Listing 4- 2 1 presents the internal implementation of the... function on it as shown in the second boldfaced portion of Listing 4- 1 9 If you run Listing 4- 1 9, you get the pop-up message shown in Figure 4- 2 Notice that this message displays the first name, last name, and employee ID, but it does not display the manager’s department This 106 c 04. indd 106 8/20/07 6:00 :41 PM Chapter 4: JavaScript Object-Oriented Programming is because the Department.Manager class inherits... run this code, you’ll get the pop-up message shown in Figure 4- 1 101 c 04. indd 101 8/20/07 6:00:39 PM Chapter 4: JavaScript Object-Oriented Programming Figure 4- 1 Note that this pop-up message shows the following code: Department.Employee = function (firstName, lastName) { var _firstName = firstName; var _lastName = lastName; } This is the boldfaced code shown in Listing 4- 1 5 — that is, the definition... internal implementation as presented in Listing 4- 1 8 Listing 4- 1 8: The resolveInheritance Method Type.prototype.resolveInheritance = function() { if(this. basePrototypePending) { var b = this. baseType; b.resolveInheritance(); for(var a in b.prototype) (continued) 103 c 04. indd 103 8/20/07 6:00 :40 PM Chapter 4: JavaScript Object-Oriented Programming Listing 4- 1 8 (continued) { var c = b.prototype[a]; if(... reflection capabilities of the ASP.NET AJAX client-side framework Listing 4 -5 : The Internal Implementation of isNamespace Type.isNamespace = function(a) { if(typeof a === “undefined” || a === null) return false; return ! ! a. namespace; }; 88 c 04. indd 88 8/20/07 6:00:35 PM Chapter 4: JavaScript Object-Oriented Programming register Interface The ASP.NET AJAX client-side framework extends Type to add support... (continued) 97 c 04. indd 97 8/20/07 6:00:38 PM Chapter 4: JavaScript Object-Oriented Programming Listing 4- 1 1 (continued) str += (“Last Name: “ + mgr.get_lastName() + “\n”); str += (“Department: “ + mgr.get_department() + “\n”); alert(str); The first order of business is to define the new Manager class or the new Manager constructor as shown in Listing 4- 1 2 Listing 4- 1 2: The... Listing 4- 1 2, the constructor of every subclass must first call the initializeBase method As discussed earlier, this method is the ASP.NET AJAX equivalent of the base syntax in C# (see Listings 4- 1 2 and 4- 1 3) As such, the main responsibility of the initializeBase method is to invoke the constructor of the base class Before diving into the internal implementation of this method, let’s revisit Listing 4- 1 2:... (“Last Name: “ + mgr.get_lastName() + “\n”); str += (“Department: “ + mgr.get_department() + “\n”); alert(str); Listings 4 -3 and 4 -8 presented portions of the internal implementation of the registerClass method Listing 4 -1 4 presents the complete code for this method Listing 4 -1 4: A Portion of the Internal Implementation of the registerClass Function Type.prototype.registerClass = function(c, b,... — that is, the Department.Employee class Figure 4- 4 Listing 4- 2 3 presents the internal implementation of the function Listing 4- 2 3: The getBaseMethod Method Type.prototype.getBaseMethod = function(d, c) { var b = this.getBaseType(); if(b) { var a = b.prototype[c]; return a instanceof Function ? a : null; } return null; }; 112 c 04. indd 112 8/20/07 6:00 :44 PM . registered with the ASP. NET AJAX client-side framework. c 04. indd 86c 04. indd 86 8/20/07 6:00: 34 PM8/20/07 6:00: 34 PM Chapter 4: JavaScript Object-Oriented Programming 87 Listing 4- 4 : The Internal. extend the ASP. NET AJAX client-side framework. c 04. indd 80c 04. indd 80 8/20/07 6:00:32 PM8/20/07 6:00:32 PM Chapter 4: JavaScript Object-Oriented Programming 81 register Class The ASP. NET AJAX client-side. as much as possible, the ASP. NET AJAX client-side framework comes with a set of extensions — known as the ASP. NET AJAX OOP and type reflection extensions — that add .NET- like OOP and type reflection

Ngày đăng: 09/08/2014, 06:23

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan