Why do you say that, if you receive an interview invitation a few days ago, you can try it. You haven't had an interview for a few years. And interviewer
This article aims to allow more programmers to understand some concepts of javascript. We already know enough about it. It's time to move closer to the deeper understanding.
Why do you say that, if you receive an interview invitation a few days ago, you can try it. You haven't had an interview for a few years. Sitting on the sofa with the interviewer, he asked me in a simple way:
Create an object that includes several public attributes. Next, create a public method for the object, and then create several private attributes and a private method for the object.
To be honest, I have a silent name for these questions. If he asks me to use jquery to write a drag plug-in or something, I guess I can write very well. The native javascript is dizzy. Although I have read the jquery source code explanation, but these basic concepts are terrible.
The example output in this article is as follows for ease of viewing:
function dwn(s){document.write(s+"
");}
Function
From the very beginning, when I got started with JavaScript, I felt flexible. Everyone's writing methods were different. For example, a function had N writing methods, such:
function showMsg(){}var showMsg = function(){}showMsg = function(){}
There seems to be no difference. They are all the same. Is it true? Let's take a look at the example below:
/// Functions // function Definition: Name function (declarative), anonymous function (referenced) // declarative, defining code before function Execution Code is parsed function t1 () {dwn ("t1");} t1 (); function t1 () {dwn ("new t1");} t1 (); // reference, dynamically parse var t1 = function () {dwn ("new t1");} t1 (); var t1 = function () {dwn ("new t1");} t1 (); // output above: new t1, new t1, new t1, new t1
I may think that I should output t1, new t1, new newt1, new t1, but the result is not like this. I should understand this sentence: declarative, the defined code is parsed before the function Execution Code.
If we take a further step, we should say that it is a scope chain problem. In fact, the first two methods are equivalent to window. t1 is a public attribute of window. It is assigned twice and the last value is the final value.
The next two methods can be understood as t1 is a variable, and the result after var of the fourth method is removed remains unchanged.
However, when the fourth method is changed to a declaration like function t1 () {}, the result is changed to new t1, new t1, new t1, the first two of new t1 can better understand why this is the answer according to my understanding. The third one can also understand it, but the last output makes me more entangled.
In addition, anonymous functions are written like (function () {...}) (). The last parenthesis is used for parameter input.
There is also a declaration such as var t1 = new function () {...}. In fact, t1 is already an object.
Var t2 = new function () {var temp = 100; // Private member this. temp = 200; // public member. The two concepts will show return temp + this after the third. temp;} alert (typeof (t2); // objectalert (t2.constructor (); // 300
In addition, a built-in function object is used to construct a function, for example:
// The result is the same if no new value is added for this position. WHYvar t3 = new Function ('var temp = 100; this. temp = 200; return temp + this. temp; '); alert (typeof (t3); // functionalert (t3 (); // 300
Create object
First, let's take a look at Object-Oriented Programming (Object-Oriented Programming, OOP). With OOP technology, many code modules are often used, and each module provides specific functions, each module is isolated and even completely independent from other modules. This modular programming method provides great diversity and greatly increases the chance of code reuse. This problem can be further illustrated by examples, assuming that a high-performance application on the computer is a first-class racing car. Using traditional programming skills, this racing car is a unit. To improve the car, you must replace the entire unit, send it back to the manufacturer, ask the car experts to upgrade it, or buy a new car. If you use OOP technology, you only need to purchase a new engine from the manufacturer and replace it with the instructions, instead of using a steel saw to cut the car body.
However, most of the arguments are that javascript is not a direct object-oriented language, but through simulation, it can do a lot of things that can be done by object-oriented languages, such as inheritance, polymorphism, encapsulation, javascript can do the following ):
/// ----------------------------------------------- // The following three methods to construct an Object // new Object, instantiate an Objectvar a = new Object ();. x = 1,. y = 2; // var B = {x: 1, y: 2}; // define the function Point (x, y) {// similar to this. x = x; this. y = y;} var p = new Point (1, 2); // instantiate the class
The first method is implemented by constructing a basic object to add attributes directly. The second method is similar to the first one, which can be seen as a quick representation of the first method. In the third method, you can create multiple objects of the same type based on "class.
Encapsulation of object attributes (public and private)
Here is an example:
Function List () {// Private member, which cannot be accessed outside the object. If there is no var declaration, m_elements will be changed to a global variable so that the external member can be accessed directly, for example, alert (m_elements [0]) var m_elements = []; m_elements = Array. apply (m_elements, arguments); // simulate getter here, alist. length; // equivalent to the getName () method: this. length = function () {return m_elements.length;}, alist. length (); // public attribute, which can be passed through ". "operator or subscript to access this. length = {valueOf: function () {return m_elements.length ;}, toString: function () {return m_elements.length ;}// public method. This method uses alert (alist) equivalent to alert (alist. toString () this. toString = function () {return m_elements.toString () ;}// public method this. add = function () {m_elements.push.apply (m_elements, arguments);} // The Private method is in the following format. The closure concept is involved here. Continue to explain // var add = function () or function add () // {// m_elements.push.apply (m_elements, arguments); //} var alist = new List (1, 2, 3); dwn (alist ); // = alert (alist. toString (), output 1, 2, 3dwn (alist. length); // output 3alist. add (, 6); dwn (alist); // output, 5, 6dwn (alist. length); // output 6
Types of attributes and Methods
In javascript, object attributes and Methods support four different types: private property, dynamic public property (dynamic public property ), static public property/prototype property (static public property or prototype property), static property (static property or class property ). Private attributes are completely inaccessible to the outside world. They can be accessed through internal getter and setter (both simulated). dynamic public attributes can be accessed from outside, and each object instance holds a copy without affecting each other; each object instance of the prototype attribute shares a unique copy. A class attribute is not an instance attribute but a class attribute.
The following is an example:
/// Dynamic // dynamic public type, static public type (prototype attribute) function myClass () {var p = 100; // private propertythis. x = 10; // dynamic public property} myClass. prototype. y = 20; // static public property or prototype property. attributes are dynamically added to the prototype of myClass, which applies to all instantiated objects. Note that prototype is used here, this is a very useful thing. // to become an advanced javascript stage, prototype and closure must understand and properly apply myClass. z = 30; // static propertyvar a = new myClass (); dwn (. p) // undefineddwn (. x) // 10dwn (. y) // 20a. x = 20;. y = 40; dwn (. x); // 20dwn (. y); // 40 delete (. x); // Delete the property xdelete (. y); // Delete the property ydwn (. x); // undefineddwn (. y); // 20 after the static public property y is deleted, it is restored to the prototype property ydwn (. z); // The undefined class attribute cannot access dwn (myClass. z );
Prototype)
Here we will only talk about this. prototype and closure can be clearly explained in a few words. If we can give you some inspiration here, we are lucky. Idiom "show Cats and tigers". Here the cat is a prototype, and the tiger is a type, which can be expressed as: Tiger. prototype = a cat or tiger. prototype = new CAT (). Because each object instance of the prototype attribute shares a unique copy, when one of the instances adjusts the value of a prototype attribute, all instances change when calling this attribute.
The following is the type chain of the prototype relationship:
Function ClassA () {} ClassA. prototype = new Object (); function ClassB () {} ClassB. prototype = new ClassA (); function ClassC () {} ClassC. prototype = new ClassB (); var obj = new ClassC (); dwn (obj instanceof ClassC); // truedwn (obj instanceof ClassB); // truedwn (obj instanceof ClassA ); // truedwn (obj instanceof Object); // true // Point Object with default values: function Point2 (x, y) {if (x) this. x = x; if (y) this. y = y;} // set x of the Point2 object. The default value of y is 0Point2. prototype. x = 0; Point2.prototype. y = 0; // p1 is a default (0, 0) object var p1 = new Point2 (); // It can be written as var p1 = new Point2 without error, WHY // p2 value: var p2 = new Point2 (1, 2); dwn (p1.x + "," + p1.y); // 0, 0dwn (p2.x + "," + p2.y ); // 1, 2delete object attributes, the prototype attributes return to the initialization status: function ClassD () {this. a = 100; this. B = 200; this. c = 300} ClassD. prototype = new ClassD (); // set the original attributes of ClassD as a prototype, including the value of ClassD. prototype. reset = function () {// delete a non-prototype attribute for (var each in this) {delete this [each] ;}} var d = new ClassD (); dwn (d. a); // 100d. a * = 2; d. B * = 2; d. c * = 2; dwn (d. a); // 200dwn (d. b); // 400dwn (d. c); // 600d. reset (); // Delete non-prototype attributes. All returned prototype dwn (d. a); // 100dwn (d. b); // 200dwn (d. c); // 300
Inheritance
If both classes are of the same instance type, there is a certain relationship between them. We call the generalization relationship between the types of the same instance as inheritance. C # and JAVA both have this. The specific understanding will not be mentioned.
In javascript, it does not support inheritance directly from methods, but as mentioned above, it can be simulated.
There are four methods: Construction inheritance, prototype inheritance, instance inheritance, and copy inheritance. After the integration, there will be a hybrid continuation method. What is this method, that is, the first four types of mixing ~
The following example involves the usage of apply, call, and some Arrays:
Construction continuation example
// Define a Collection type function Collection (size) {this. size = function () {return size}; // public method, which can be inherited} Collection. prototype. isEmpty = function () {// static method, cannot be inherited return this. size () = 0;} // defines an ArrayList type, which "inherits" Collection type function ArrayList () {var m_elements = []; // Private member, m_elements = Array. apply (m_elements, arguments); // The ArrayList type inherits Collection this. base = Collection; this. base. call (this, m_elements.length); this. add = function () {return m_elements.push.apply (m_elements, arguments);} this. toArray = function () {return m_elements;} ArrayList. prototype. toString = function () {return this. toArray (). toString ();} // defines a SortedList type, which inherits the function SortedList () of the ArrayList type. {// SortedList inherits the ArrayListthis type. base = ArrayList; this. base. apply (this, arguments); this. sort = function () {var arr = this. toArray (); arr. sort. apply (arr, arguments) ;}// construct an ArrayListvar a = new ArrayList (1, 2, 3); dwn (. size (); // a inherits the size () method dwn (. isEmpty); // but a does not inherit the isEmpty () method // constructs a SortedListvar B = new SortedList (3,1, 2); B. add (4, 0); // B inherits the add () method dwn (B. toArray (); // B inherits toArray () method B from ArrayList. sort (); // The sort () method dwn (B. toArray (); dwn (B. size (); // B inherits the size () method from the Collection.
Prototype inheritance law example
// Define a Point type function Point (dimension) {this. dimension = dimension;} // defines a Point2D type, "Inheriting" Point type function Point2D (x, y) {this. x = x; this. y = y;} Point2D. prototype. distance = function () {return Math. sqrt (this. x * this. x + this. y * this. y);} Point2D. prototype = new Point (2); // Point2D inherits the Point // defines a Point3D type, and also inherits the Point type function Point3D (x, y, z) {this. x = x; this. y = y; this. z = z;} Point3D. prototype = new Point (3); // Point3D also inherits Point // constructs a Point2D object var p1 = new Point2D ); // construct a Point3D object var p2 = new Point3D (0, 1, 2); dwn (p1.dimension); dwn (p2.dimension); dwn (p1 instanceof Point2D ); // p1 is a Point2Ddwn (p1 instanceof Point); // p1 is also a Pointdwn (p2 instanceof Point); // p2 is a Point
The above two methods are the most commonly used.
Example of instance inheritance law
Before giving an example of this method, let's talk about the limitations of constructing the inheritance method as follows:
Function MyDate () {this. base = Date; this. base. apply (this, arguments);} var date = new MyDate (); // undefined, date is not inherited to the Date type, so there is no toGMTString method alert (date. toGMTString );
Some methods of the core object cannot be inherited by the constructor because the core object is not changed to the prototype Inheritance Method in the constructor as the custom general object ?, As follows:
Function MyDate () {} MyDate. prototype = new Date (); var date = new MyDate (); // '[object]' is not a Date object and is still not inherited to the Date type! Alert (date. toGMTString );
Now, change to the instance inheritance law:
Function MyDate () {// instance is a newly created Date object var instance = new Date (); instance. printDate = function () {document. write (""+ Instance. toLocaleString () +"
");} // Extend the printDate () method to the instance return instance; // return the instance as the return value of the constructor} var myDate = new MyDate (); // This time the correct time string is successfully output. It seems that myDate is already an instance of Date and inherits the successful dwn (myDate. toGMTString (); // if no return instance exists, the following table cannot be accessed because it is the private object method myDate. printDate ();
Copy inheritance law example
Function. prototype. extends = function (obj) {for (var each in obj) {this. prototype [each] = obj [each]; // one-to-one copy of object attributes, however, it is slow and prone to problems. // This "inheritance" method is generally not recommended.} var Point2D = function (){//......} Point2D. extends (new Point ()){//......}
This inheritance law seems to be rarely used.
Hybrid inheritance example
Function Point2D (x, y) {this. x = x; this. y = y;} function ColorPoint2D (x, y, c) {Point2D. call (this, x, y); // here constructor inheritance is called, and the constructor of the parent class is called. // It is equivalent to // this. base = Point2D; // this. base. call (this, x, y); this. color = c;} ColorPoint2D. prototype = new Point2D (); // prototype inheritance is used here, so that ColorPoint2D uses Point2D object as the prototype.
This article is available at http://www.nowamagic.net/librarys/veda/detail/488.