Javascript object-oriented development (I), javascript object-oriented

Source: Internet
Author: User
Tags hasownproperty

Javascript object-oriented development (I), javascript object-oriented
1. js object-oriented Introduction

Javascript is the most widely used web Front-End scripting language with its flexibility, ease of use, and ease of use. Previously, I used JavaScript For data verification, event binding, dom, and other operations in my project, however, as the project becomes more and more complex, we have to deal with js object-oriented development. Although js has traces of learning from java in many places, it is still quite different from java in terms of object-oriented programming. It does not have keywords such as class and interface. On the contrary, it is very simple. It only uses the function keyword, And it replaces the class with a name called a prototype object. We define a class in java and usually use the following format:

<pre name="code" class="java">class A{    private String name;    ......}
 

In js, we use the following method to define a class:

Function Cat () {// define a Cat prototype object (class )}
If we call Cat (), Cat is used as a common function. If var cat = new Cat (); then Cat is used as a class. Since both common functions and classes are modified with the same keyword function, the code readability is reduced. Therefore, we generally agree that for a function, the first letter is lowercase (such as cat), and for a class, the first letter is capitalized (such as Cat ).

In java, we generally get used to defining classes first and then creating class instances for use. Follow the idea of defining a mold first, and then using a mold to produce products. But Javascript is different. It is very loose and can even dynamically add attributes and methods to the instance, such:

<Pre name = "code" class = "javascript"> // dynamically Add the property var cat = new Cat (); cat. name = ""; alert (cat. name); // Tom


 
// Dynamic addition method cat. sayHello = function () {alert (this. name);} cat. sayHello (); // white

Although this method is very flexible, it violates the object-oriented design principles to some extent. Therefore, we do not recommend this method. It is best to imitate the java practice, first define the class, and then instantiate the object.

In java, we obtain the attributes of an object, which are usually obtained using the object name. attribute name. In js, in addition to this, you can also use the object name ["attribute name"] (Note that [] is passed as a string). This benefits dynamic access, we can use this feature for some technical programming. Later we will introduce the example of using this feature to simulate map in java. Of course, if this object does not have a certain attribute, such as alert (cat. age); this call will display undefined.

If we assign a cat instance to another reference variable, such as var cat2 = cat, cat and cat2 both point to the same instance object. If we change cat. name = "2", cat2.name will also become" 2". I believe this should be very understandable. But if we set cat2 = null, what will cat point? It should also point to the original heap and will not point to null. This should be noted in programming. I have suffered this loss in previous projects.

Ii. How js creates objects 1. How Factory

Similar to java, js also has a superclass called Object. Instead of defining classes, we can directly use an Object to get an instance, and then use the aforementioned method of dynamically adding attributes and methods for development. Although this method is not used in actual projects, as the simplest way to create objects, I think it is necessary to understand its implementation method. Let's look at the following code:

Var a = new Object (); // or var a = {}. name = "123"; alert (. name); // 123. getName = function () {return this. name;} alert (. getName (); // 123.

Var a = new Object (); this is a standard factory method for creating objects. Of course, we can also abbreviated it as var a = {}. The two statements are equivalent, but obviously, the second method is simpler. In many underlying code, more will adopt the second method. Another purpose of this mode is to introduce an Object method: defineProperty. It can also add attributes or methods to the instance Object. The usage is as follows:

Object. defineProperty (a, "age", {writable: false, // false: Read-Only true: modifiable retriable: true, // true: delete. age Delete this attribute enumerable: true, // value: 13 // Initial value} can be enumerated); alert (. age); // 13
DefineProperty can receive three parameters. The first parameter is the instantiated object, the second parameter is the attribute or method name to be added, and the third parameter can set some attributes for the attribute and method. The code above indicates that an age attribute is added to the instantiated object a, which cannot be modified, deleted, or enumerated. Its value is 13. We will introduce this method for the time being. We will use this method to optimize the code when we talk about prototype.

2. constructor Mode
Function B (name, age) {this. name = name; // publicvar age = age; // privatethis. getName = function () {// publicalert (this. name);} var getAge = function () {// privatealert (this. age) ;}} var B = new B ("tim", 9); B. getName (); // tim B. getAge (); // Error
Using constructors to define classes should be the most commonly used method in daily application development. This method has a little trace of java. It should be noted that in js, attributes or methods are only public and private without protected. If var is written, it indicates private. If this is written, it indicates public. Therefore, getName can be called successfully, but getAge cannot. Note: this in js has always been a confusing keyword. My generalization of this is: Who calls it, and this points to who.

Note that every time an object is created, a copy of the code is copied using the constructor to define the class. That is to say, if we create var b1 = new B ("tim", 9); and var b2 = new B ("tom", 10); these two instantiated objects, the code they hold is not shared and independent from each other, which will inevitably lead to a waste of memory space. This is also the biggest drawback of the constructor definition class. To make up for this defect, the concept of prototype is proposed, through which class attributes or methods are defined, all objects will share the same code, greatly reducing the overhead of memory space.

3. Original Method

As mentioned above, prototype allows all instantiated objects to share the same code. Let's take a look at its usage.

Function C () {} C. prototype. name = "tom"; // class-Level Attribute C. prototype. getName = function () {// class-level method <span style = "white-space: pre"> </span> return this. name ;}
The method for creating objects and calling object attributes is the same as the constructor mode. The only difference is that the prototype attribute and method are used on the class rather than the object, which is similar to the static function of java. We need to note that prototype cannot go to the private methods and attributes of the classes. For example, we have defined a private variable age: var age = 10 for the class C; then add a getAge Method on prototype: C. prototype. getAge = function () {alert (age);} this method is not allowed. If you call it, undefined is displayed.

Prototype also has a strong role in extending the original class. We know that the Array monomer class provides a forEach Method for us to traverse Array elements, but it cannot process multi-dimensional arrays. We can use prototype to add an each method for processing multi-dimensional arrays for Array, so we can do this:

// Add the method Array that can be a circular multi-dimensional Array to the Array. prototype. each = function (fn) {if (this & this. length> 0 & fn. constructor = Function) {// The array exists and has a length greater than 0. The passed parameter is a Function (callback Function) var index = 0; for (var I = 0; I <this. length; I ++) {var element = this [I]; if (element. constructor = Array) {// It is still an Array. Call each again to form a recursive element. each (fn);} else {fn. call (element, element, I) ;}}// use arr = [1, 2, [3, 4, [5, 6]; arr. each (function (element, I) {alert (element );});
Here we need to distinguish between the attributes and methods defined by the constructor and the prototype is applied to the class. Prototype is a pointer that points to a class prototype object. In this prototype object, we can add attribute methods. In addition, it also holds a constructor attribute, which is essentially a class constructor. The following describes the relationships between constructors, prototype objects, and instance objects through pseudocode:

1. constructor. prototype = prototype object
2. Prototype object. constructor = constructor Template
3. Prototype object. isPrototypeOf (Instance Object) = true

Let's take a look at the example below. By the way, we also introduce some common APIs related to object-oriented in js.

Function C () {} C. prototype. name = "tom"; // all instances share var c = new C (); alert ("name" in c); // true if you can access name, true is distinguished from hasOwnProperty. alert (c. name); // tom, but this attribute does not belong to the instance but belongs to the prototype alert (c. hasOwnProperty ("name"); // false because it is a prototype c. name = "my"; // overwrite the prototype attribute, and the name is changed to its own attribute alert (c. name); // myalert (c. hasOwnProperty ("name"); // truedelete c. name; // your name attribute is missing, but the prototype is still in alert (c. name); // tomc. name = 111; alert (Object. keys (c); // print all attributes of c (excluding prototype), and the return value is an array object.
Note: If the constructor and prototype have attributes of the same name, the constructor will be queried first during the call.

4. Previously, we mentioned that prototype is a pointer pointing to the prototype object of this class. In this case, can we rewrite what the Pointer Points? The answer is yes. Let's take a look at the method of defining the class below the category:

Function Person () {}// rewrite the Person prototype. prototype = {name: "py", age: 11, sayHello: function () {alert (this. name) ;}}; var person = new Person (); person. sayHello (); alert (person. constructor); // funciton Object (){}

We can see that we can use a json-like key-value method to define class-level attributes and methods. Some people call it a simple prototype. I believe that reading this code should be easier, and the only doubt should be the last line of code. Because prototype has a constructor attribute whose value is the constructor of the class, in theory, alert should generate the function Person () {}. How can it be an Object? The reason is that we have changed the prototype pointer and its prototype has changed to an Object. If you want to change to Person, the first thought is to write: constructor: Person; in Person. prototype = ;. This method is feasible, but constructor, a constructor in js, cannot be enumerated. This rewrite will destroy this rule. In this case, we can use the defineProperty mentioned above to rewrite it. The Code is as follows:

Function Person () {}// rewrite the Person prototype. prototype = {// constructor: Person, name: "panye", age: 11, sayHello: function () {alert (this. name) ;}}; Object. defineProperty (person, "constructor", {enumerable: false, // value: Person} cannot be enumerated });
Then execute alert (person. constructor); funciton Person () {} will pop up (){}.

Iii. Object-oriented applications 1. Common object-oriented design methods for development the above mentioned constructor mode creates an object, which wastes some memory space because its code is not shared. Although the prototype method can share the code, this feature has become a drawback. For example, if I have created two Person instances and changed the name attribute of one instance to "2", the name attribute of the other instance will change accordingly, this is what we don't want to see. Therefore, in formal development, we often combine the two practices to learn from each other. We know that the essence of different instances of the same class is not the method, but the attribute. For example, when people speak and walk, the difference lies in our different names and weights. Therefore, during development, we can use constructors to define attributes and use the original method to define methods.

Function Person (name, age) {// the property does not share this. name = name; this. age = age;} // method sharing: Person. prototype = {constructor: Person, // you can use defineProperty to optimize and improve the sayHello: function () {alert (this. name + this. age) ;}}// create an instance var p1 = new Person ("tim1", 12); var p2 = new Person ("tim2", 14); p1.sayHello (); // timerep2. sayHello (); // tim214

2. Using object-oriented feature simulation to implement java's Mapjs does not provide us with a set type. We can simulate Map using arrays and other methods, but considering the features of Map: key-value pairs and keys cannot be repeated. We can use the features of classes in js to simulate the implementation.

Function Map () {var obj = new Object (); // stores the key-value Pair and uses the key as the property of the obj, and the value as the property value. // Add this. put = function (key, value) {obj [key] = value;} // obtain the length of this. size = function () {var count = 0; for (var a in obj) {count + = 1;} return count ;}// obtain this based on the key. get = function (key) {return obj [key];} // delete this. remove = function (key) {delete obj [key];} // cyclically traverse this. forEach = function (fn) {for (var a in obj) {fn (a, obj [a]) ;}} var map = new Map (); map. put ("01", "aaa"); map. put ("02", "vvv"); map. put ("03", "bbb"); alert (map. size (); // 3 alert (map. get ("03"); // bbbmap. remove ("03"); alert (map. size (); // 2 alert (map. get ("03"); // undfined map. forEach (function (key, value) {alert (key + "" + value );});
Note: The above code is just intended to illustrate the programming ideology. Some special cases are taken into account in formal business processing. If you are interested, you can improve the code.

4. I ended my blog and introduced the basics of js object-oriented and several ways to create objects. In the next blog, I will share with you how to implement inheritance and Interface Programming in js and the implementation of common js-based design patterns.

I am a web Front-end cainiao. If an incorrect description is displayed in my blog, please correct me!


Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.