A detailed programming paradigm in jquery _jquery

Source: Internet
Author: User
Tags aop event listener extend inheritance tagname uuid wrapper jquery library

In this paper, the programming paradigm in jquery is analyzed in detail. Share to everyone for your reference. Specifically as follows:

The face of the browser front-end programming has undergone profound changes since 2005, which does not simply mean that there is a large number of functional base libraries, making it easier for us to write business code, and, more importantly, the idea that we look at the front-end technology has undergone a major shift, Be aware of how to release programmer productivity in a way that is unique to the front-end. This will be combined with the principles of the jquery source code, a simple introduction to the programming paradigm and common techniques that emerge in JavaScript.

1. AJAX: Status resident, asynchronous update

First look at a little history.

A. In 1995, Netscape's Brendan Eich developed the Javacript language, a dynamic, weakly typed (weakly typed), prototype-based (prototype-based) scripting language.
B. Microsoft IE5 released in 1999, which contains XMLHTTP ActiveX controls.
C. Microsoft IE6 released in 2001, partially supporting the DOM Level 1 and CSS 2 standards.
D. 2002 Douglas Crockford invented the JSON format.

At this point, it can be said that Web2.0 rely on the technical elements have been basically formed, but did not immediately in the entire industry has a significant impact. Although some of the "page asynchronous local Refresh" techniques in the middle of the secret spread of the programmer, and even gave birth to bindows such a large and bloated class library, but overall, the front-end is seen as a poor and dirty swamp, only the background technology is kingly. What's missing?

When we stand in today's perspective to review the JS code before 2005, including those of the cattle at the time of the code written, you can clearly feel their control of the process of weakness. Not that the 2005 JS technology itself has problems, but they are in the conceptual level is disunity, the lack of unity of concept, or lack of their own unique style, their soul. At that time, most of the people, most of the technology are trying to simulate the traditional object-oriented language, using the traditional object-oriented technology, to achieve the traditional GUI model of the imitation.

The 2005 is a year of change and a year of creative concepts. With the release of a series of refreshing interactive apps from Google, Jesse James Garrett's article "Ajax:a New approach to WEB applications" has been widely disseminated. Ajax, the unique concept of the front-end, quickly unifies many scattered practices under the same slogan, triggering the transformation of the Web programming paradigm. The so-called wrong name is not smooth, the unknown people can find the organization. Before Ajax, people have already recognized the B/s architecture is the essence of the browser and server state space is separated, but the general solution is to hide this distinction, the foreground state synchronization to the background, by the background of the unified logic processing, such as asp.net. Because the lack of mature design mode to support the presence of the front, in the page change, the already loaded JS object will be forced to discard, so who can expect it to complete what complex work?

Ajax explicitly proposed that the interface is locally refreshed, the foreground resides in the state, which contributed to a need: the need for JS objects in the foreground for a longer period of time. This means that these objects and functions need to be managed effectively, meaning more complex code organization techniques, which means a desire for modularity and for the common code base.

The part of jquery's existing code that really is relevant to Ajax (using the XMLHTTP control to access back-end data asynchronously) is rare, but without Ajax, jquery is a common code base that lacks justification.

2. modularity: Managing name Spaces

When a lot of code comes out, the most basic concept we need is modularity, which is to decompose and reuse the work. The key to the breakdown of work is that the results of individual work can be integrated together. This means that each module must be based on a consistent underlying concept that enables interaction, i.e. it should be based on a set of common code bases, masking the inconsistencies of the underlying browsers, and implementing a unified abstraction layer, such as a unified event management mechanism. More important than the unified code base is that there must be no name conflict between the modules. Otherwise, you cannot work together even if there is no interaction between the two modules.

One of the main selling points of JQuery's current advocacy is good control over namespaces. It's even more important than providing more and better functional points. Good modularity allows us to reuse code from any source, and everyone's work accumulates. and functional realization is just a matter of a temporary workload. jquery uses a variant of module pattern to reduce the impact on the global namespace, adding a jquery object (that is, the $ function) to the Window object.

The key of the so-called module pattern code is to use anonymous functions to limit the scope of temporary variables.

Copy Code code as follows:
var feature = (function () {

private variables and functions
var privatething = ' secret ',
Publicthing = ' Not secret ',

changeprivatething = function () {
privatething = ' super secret ';
},

sayprivatething = function () {
Console.log (privatething);
Changeprivatething ();
};

Returns an externally exposed API
return {
Publicthing:publicthing,
Sayprivatething:sayprivatething
}
})();

JS itself lacks package structure, but after years of trying the industry has gradually unified the understanding of the Baugacai, forming a requirejs library to get a certain consensus solution. jquery can be integrated with the Requirejs library to achieve better module dependency management. Http://requirejs.org/docs/jquery.html

Copy Code code as follows:
Require (["jquery", "jquery.my"], function () {
Executed after Jquery.js and Jquery.my.js were successfully loaded
$ (function () {
$ (' #my '). MyFunc ();
});
});






The following function is used to define the module My/shirt, which relies on the My/cart and my/inventory modules,


Copy Code code as follows:
Require.def ("My/shirt",


["My/cart", "My/inventory"],


function (cart, inventory) {


Here, module pattern is used to return the externally exposed API of My/shirt modules.


return {


Color: "Blue",


Size: "Large"


Addtocart:function () {


Decrement is a my/inventory external exposure API.


Inventory.decrement (this);


Cart.add (this);


}


}


}


);

3. The Magic $: Object elevation

What do you think of when you first see the $ function? Traditional programming theory always tells us that the function name should be accurate, should express the author's intention clearly and accurately, even claiming that long name is superior to the short name, because it reduces the possibility of ambiguity. But, what is $? Garbled? The information it conveys is too vague and ambiguous. $ is invented by the Prototype.js library, it's really a magical function because it can elevate an original DOM node (enhance) into an object with complex behavior. In the initial implementation of Prototype.js, the $ function is defined as

Copy Code code as follows:
var $ = function (ID) {
Return "string" = = typeof ID? document.getElementById (ID): ID;
};

This basically corresponds to the following formula
E = $ (ID)

This is by no means merely providing a clever acronym for the function name, but more importantly, establishing a one by one correspondence between the text ID and the DOM element at the conceptual level. Before $, the distance between the ID and the corresponding element is very remote, and the element is typically cached in a variable, such as

Copy Code code as follows:
var ea = Docuement.getelementbyid (' a ');
var EB = Docuement.getelementbyid (' B ');
Ea.style .....



But when you use $, you can read the following wording


Copy Code code as follows:
$ (' Header_ ' +id). Style ...
$ (' body_ ' +id) ....



The distance between ID and element seems to be eliminated and can be very tightly intertwined.

Prototype.js later expanded the meaning of the $,

Copy Code code as follows:
function $ () {
var elements = new Array ();

for (var i = 0; i < arguments.length; i++) {
var element = Arguments[i];
if (typeof element = = ' String ')
element = document.getElementById (element);

if (arguments.length = 1)
return element;

Elements.push (Element);
}

return elements;
}

This corresponds to the formula:
[E,e] = $ (id,id)

Unfortunately, this step prototype.js, this approach has little practical value.
The real move is to jquery, whose $ corresponds to the formula
[O] = $ (selector)
Here are three enhancements:
A. Selector is no longer a single node locator, but rather a complex set selector
B. The returned element is not the original DOM node, but rather the rich-behavior object that is further enhanced by jquery and can start a complex function call chain.
C. $ The returned wrapper object is styled in an array form, integrating the collection operations naturally into the call chain.

Of course, the above is just a simplistic description of the magic $, and its actual functionality is much more complex. In particular, there is a very common direct construction function.

Copy Code code as follows:
$ ("<table><tbody><tr><td>...</td></tr></tbody></table>") ....

jquery constructs a series of DOM nodes directly from the incoming HTML text and wraps them as jquery objects. This can be seen in some way as an extension of the selector: the HTML content description itself is a unique designation.

$ (function{}) This feature is really a bit of a silent, it means that when the Document.ready call this callback function. Really, $ is a magical function, have any questions, please $.

To sum up, $ is the transition channel from the ordinary Dom and text description world to the jquery world with rich object behavior. Crossed the door, came to the ideal country.

4. Amorphous parameters: Focus on expression rather than constraint

Weak type language since the top of the head with a "weak" word, it is inevitable that people have a somewhat congenitally deficient feeling. Is it really a major drawback to lack of a type constraint in a program? In traditional strongly typed languages, the type and number of function parameters are the constraints that the compiler is responsible for checking, but these constraints are still far from sufficient. In general applications to enforce constraints, there will always be a large number of defensive code, such as in C + + we often use Assert, and in Java also frequently need to judge the range of parameter values

Copy Code code as follows:
if (Index < 0 | | | index >= size)
throw New Indexoutofboundsexception (
"Index:" +index+ ", Size:" +size);



Obviously, this code will lead to a large number of non-functional execution paths in the program, that is, we make a lot of judgments, the code executes to a point, the system throws an exception, yells blocked. If we change our mind, now that we have made some judgments, can we use the results of these judgments to do what? JavaScript is a weak type of language, it is unable to automatically constrain the parameter type, if the flow of the line, further weakening the parameters of the form, the "weak" to advance to a kind of extreme, in the weak can not be weak, weak will become a hallmark of the characteristics?

Take a look at the event binding function bind in jquery,
A. Binding one event at a time

Copy Code code as follows:
$ ("#my"). Bind ("MouseOver", function () {});



B. Binding multiple events at a time
Copy Code code as follows:
$ ("#my"). Bind ("mouseover mouseout", function () {})



C. In another form, the same binding of multiple events


Copy Code code as follows:
$ ("#my"). Bind ({mouseover:function () {}, Mouseout:function () {});



D. Want to pass parameters to an event listener


Copy Code code as follows:
$ (' #my '). Bind (' click ', {foo: ' xxxx '}, function (event) {Event.data.foo.})



E. Want to group event listeners


Copy Code code as follows:
$ ("#my"). Bind ("Click.mygroup″, Function () {});"



F. Why is this function not crazy???





Even if the type is uncertain, what is the meaning of the parameter in the fixed position always determined? 10,000 step back, even if the parameter position is not important, the meaning of the function itself should be determined? But what is this?

Take value = O.val (), Set value O.val (3)

How can a function be so excessive that it behaves differently depending on the type and number of incoming arguments? Do you dislike it? But this is our values. Since it cannot be prevented, it is deliberately allowed. Although the form is changeable, but there is no one word of nonsense. Lack of constraint, no impediment to expression (I'm not scary).

5. Chain Operation: Linearization of the step-by-step refinement

The main selling point of jquery's early days was the so-called chain operation (chain).

Copy Code code as follows:
$ (' #content ')//find content Element
. Find (' H3 ')//Select all Descendants H3 nodes
. EQ (2)//filter collection, keep the third element
. HTML (' Change text for third H3 ')
. End ()//Return to the H3 collection at the previous level
. EQ (0)
. HTML (' Change the first H3 text ');

In the general imperative language, we always need to filter the data in many nested loops, and the code that actually manipulate the data is entangled with the code that locates the data. jquery uses the first to construct the set and then apply the function to the set to realize the decoupling of the two kinds of logic, and realize the linearization of the nested structure. In fact, we do not need the idea of a process to be able to intuitively understand a set, such as $ (' div.my input:checked ') can be seen as a direct description, rather than the process of tracking the behavior.

The cycle means that our thinking is in a state of repeated wrapping, and linearization then goes straight in one direction, greatly reducing the burden of thinking and improving the combination of code. To reduce the interruption of the call chain, jquery invented a brilliant idea: the jquery wrapper object itself is similar to an array (set). The collection can be mapped to a new collection. A set can be limited to its own subset, the initiator of the call is a collection, the return result is a set, the set can occur some structural change but it is a set, the set is a certain conceptual fixed point, which is the design idea drawn from the functional language. Collection operations are too common, and in Java it is easy to see that a large number of so-called encapsulation functions actually encapsulate some collection traversal operations, while the collection operations in jquery are too straightforward to encapsulate.

Chained invocation means that we always have a "current" object, all of which are for this current object. This corresponds to the following formula
x = = DX
Each step of the call chain is an incremental description of the current object and is a step-by-step process for the final goal. This idea is also widely used in the Witrix platform. In particular, in order to realize the integration of platform mechanism and business code, the platform will provide the default content of object (container), and the business code can be refined on this basis, including canceling default settings.

In other words, while the seemingly jquery chain call is simple, internal implementations have to write more loops of their own, because the compiler does not know that "automatically applies to each element of the collection".

Copy Code code as follows:
$.fn[' somefunc ' = function () {
Return This.each (function () {
Jquery.somefunc (this,...);
}
}






6. Data: Unified information Management

As a JS library, a big problem that must be solved is the State association and collaborative management problem between JS object and Dom node. Some JS library to choose JS Object, in the JS object member variable to save the DOM node pointer, always visit the JS object as the entry point, through the JS function to manipulate the DOM object indirectly. In this package, the DOM node is actually just a low-level "assembler" of the interface presentation. The choice of jquery is similar to that of the Witrix platform, which is based on the HTML structure and promotes the function of the JS enhanced (enhance) DOM node to an extended object with complex behavior. The idea here is non-invasive design (non-intrusive) and graceful degradation mechanisms (graceful degradation). The semantic structure is complete in the basic HTML level, and JS is to enhance the interaction behavior and control the presentation form.

If each of us accesses the corresponding wrapper object in the way of $ (' #my '), where is the state variable that needs to be kept for a long time? jquery provides a unified global data management mechanism.

Get Data:

Copy Code code as follows:
$ (' #my '). Data (' myattr ')



To set the data:
Copy Code code as follows:
$ (' #my '). Data (' MyAttr ', 3);



This mechanism naturally integrates the processing of the data attribute of HTML5.


Copy Code code as follows:
<input id= "My" data-my-attr= "4" .../>

Using $ (' #my '). Data (' myattr ') will be able to read the settings in HTML.

The first time you access data, jquery assigns a unique UUID to the DOM node and then sets it on a specific expando property of the DOM node, and jquery guarantees that the UUID is not duplicated on this page.

Copy Code code as follows:
Elem.nodetype? jquery.cache[Elem[jquery.expando]]: elem[Jquery.expando];



The above code can handle both the DOM node and the pure JS object. If it is a JS object, then the data is placed directly in the JS object itself, and if it is a DOM node, the cache is unified management.

Because all data is managed in a unified database, including all event listener functions (data.events), jquery can safely implement resource management. At the time of the clone node, you can automatically clone its associated event listener function. When the content of the DOM node is replaced or the DOM node is destroyed, jquery can automatically dismiss the event listener and safely release the relevant JS data.

7. Event: Unified Incident Model

The picture of "events propagating along the object Tree" is the essence of the object-oriented programming model. The composition of the object is a stable description of the interface structure, which occurs continuously at a node in the object tree and propagates up through the bubbling mechanism. The object tree naturally becomes a control structure, and we can listen to events on all child nodes on the parent node without having to explicitly associate with each child node.

In addition to creating a unified abstraction for the event models for different browsers, jquery has mainly been enhanced as follows:
A. The customization event (custom) mechanism has been added. The propagation mechanism of an event is irrelevant to the content of the event itself in principle, so the custom event can be used in the same way as the browser-built event through the same processing path. Using custom events can enhance the cohesion of your code and reduce code coupling. For example, if there is no custom event, the associated code often requires direct manipulation of related objects

Copy Code code as follows:
$ ('. Switch,. Clapper '). Click (function () {
var $light = $ (this). Parent (). Find ('. Lightbulb ');
if ($light. Hasclass (' on ')) {
$light. Removeclass (' on '). addclass (' off ');
} else {
$light. Removeclass (' off '), addclass (' on ');
}
});



And if you use custom events, the semantics of the expression are more introverted and unambiguous,


Copy Code code as follows:
$ ('. Switch,. Clapper '). Click (function () {
$ (this). Parent (). Find ('. Lightbulb '). Trigger (' changestate ');
});



B. Increased event monitoring for dynamically created nodes. The BIND function registers only the listener functions on a DOM node that already exists. For example


Copy Code code as follows:
$ (' Li.trigger '). Bind (' click ', Function () {}}

If you create another Li node after you call bind, the click event for that node is not monitored.

The delegate mechanism of jquery registers the listener functions on the parent node, and the events that are triggered on the child nodes are automatically distributed to the corresponding HANDLERFN according to the selector. This allows you to now register to listen for future-created nodes.

Copy Code code as follows:
$ (' #myList '). Delegate (' Li.trigger ', ' click ', HANDLERFN);

Recently jQuery1.7 unified the BIND, live and delegate mechanism, the world unified, only On/off.

Copy Code code as follows:
$ (' Li.trigger '). On (' click ', HANDLERFN); Equivalent to bind
$ (' #myList '). On (' Click ', ' Li.trigger ', HANDLERFN); Equivalent to delegate






8. Animation queue: Global clock Coordination

Aside from the implementation of jquery, let's consider what we need to do if we want to achieve the animation effect on the interface. For example, we want to increase the width of a div from 100px to 200px within 1 seconds. It's easy to see that for a while we need to adjust the width of the div from time to time, [and] we need to execute other code. Unlike a normal function call, we cannot expect to get the desired result immediately after the animated instruction is made, and we cannot wait for the result to come in situ. The complexity of the animation lies in: a one-time expression after a period of time to execute, and a number of logical execution paths to start at the same time, how to coordinate?

Sir Isaac Newton, in the mathematical principles of natural philosophy, wrote: "Absolute, real and mathematical time itself is passing." All events can be aligned on the timeline, which is their intrinsic coordination. So in order to execute from step A1 to A5, and to execute step B1 to B5, we only need to execute [T1, A1] at B1 time, execute [T2] at a2,b2 time, and so on.
T1 | T2 | T3 | T4 | T5 ...
A1 | A2 | A3 | A4 | A5 ...
B1 | B2 | B3 | B4 | B5 ...

A specific form of implementation can be
A. For each animation, it is divided into a animation object, with several steps inside.
Animation = new Animation (div, "width", 100,200,1000,
The interpolation function responsible for the step segmentation, the callback function when the animation is finished;
B. Registering an animated object in the global manager
Timerfuncs.add (animation);
C. At each trigger time of the global clock, advance each registered execution sequence and, if it is finished, remove it from the global manager.

Copy Code code as follows:
For each animation in Timerfuncs
if (!animation.doonestep ())
Timerfuncs.remove (animation)


Solve the principle problem, and then look at the problem of expression, how to design interface functions in the most compact form to express our intentions? The practical problems we often need to confront:

A. There are multiple elements to perform a similar animation
B. Each element has multiple properties to change at the same time
C. Start another animation after you finish performing an animation
jquery's answers to these questions can be said to have squeezed the last bit of the residual value of JS's grammatical expressive power.

Copy Code code as follows:
$ (' input ')
. Animate ({left: ' +=200px ', Top: ' 300 '},2000)
. Animate ({left: '-=200px ', top:20},1000)
. Queue (function () {
Here Dequeue will execute the last function in the queue first, so alert ("Y")
$ (this). Dequeue ();
Alert (' x ');
})
. Queue (function () {
Alert ("Y");
If you do not actively dequeue, the queue execution is interrupted and does not go on automatically.
$ (this). Dequeue ();
});

A. Use jquery's built-in selector mechanism to naturally express the processing of a set.
B. Using a map to express multiple property changes
C. Use of micro-format to express domain-specific differential concepts. ' +=200px ' represents an increase of 200px on the basis of existing values
D. Automatically define the order in which the animation is executed, using the order of the function calls: the animation that is appended to the execution queue will naturally have to wait until the previous animation has been fully executed before starting.

The implementation details of the jquery animation queue are as follows:

A. The animate function is actually call queue (function () {The end of execution requires a call to dequeue, otherwise the next method will not be driven})
When the queue function executes, if it is a FX queue and no animation is currently running (the second execution function will wait in the queue if two consecutive animate are called), the Dequeue action is automatically triggered and the drive queue runs.
In the case of a FX queue, Dequeue automatically adds a "inprogress" string at the top of the queue, indicating that the animation will be performed.
B. Create a Jquery.fx object for each property. The Fx.custom function (equivalent to start) is then invoked to start the animation.
The C. Custom function registers the Fx.step function in the global Timerfuncs, and then attempts to start a global timer.
Timerid = SetInterval (Fx.tick, fx.interval);
D. In the static tick function, the step function of each FX is called in turn. In the step function, the current value of the property is computed by easing, and then the update of the FX is invoked to update the property.
E. FX step function to determine if all property changes have been completed, call Dequeue to drive the next method.

Interestingly enough, many of the implementation code for jquery is a relay trigger code: If you need to perform the next animation, take out the execution and start the timer if you need to start the timer. This is because the JS program is single-threaded, the real execution path is only one, in order to ensure that the execution clues are not interrupted, functions have to help each other. It can be expected that if there are multiple execution engines within the program, or even an infinite number of execution engines, the face of the program will change in nature. In this case, recursion is a more natural description than a loop.

9. Promise Model: Identification of causal relationships

In reality, there are always so many time lines in the evolution of independence, people and things in time and space staggered, but no causal. Software, functions in the source code in line, will inevitably produce some questions, with what row in front of the first to implement? Don't you have it without me? Let the whole universe shout 1,2,3 march forward, from God's point of view, is probably the management difficulty is too big, then has the relativity theory. If there is no exchange of information between each other and there is no interdependence, then the sequence of events in one coordinate system may appear to be reversed in another coordinate system. The programmer invented the promise pattern by painting the gourd.

Promise and future patterns are basically the same thing, let's take a look at the familiar future patterns in Java.

Copy Code code as follows:
Futureresult = DoSomething ();
...
Realresult = Futureresult.get ();

Making a function call simply means that one thing has happened, and it does not necessarily mean that the caller needs to know the end result. The function immediately returns a Promise (future type) that will be cashed in the future, which is actually some sort of handle. The handle is passed, and the code in the middle of the transfer is indifferent to what the actual result is and whether it has returned. Until a piece of code needs to rely on the result returned by the call, so it opens the future and looks at it. If the actual result has been returned, Future.get () immediately returns the actual result, or the current execution path will be blocked until the result is returned. Subsequent calls to Future.get () are always returned immediately, since the causal relationship has been established and [the result returns] The event must have occurred before and will not change.

The future mode is typically an external object that actively views the return value of the future, while the promise mode registers the callback function on the promise by an external object.

Copy Code code as follows:
function GetData () {
Return $.get ('/foo/'). Done (function () {
Console.log (' Fires after the AJAX request succeeds ');
}). Fail (function () {
Console.log (' Fires after the AJAX request fails ');
});
}

function Showdiv () {
var DFD = $. Deferred ();
$ (' #foo '). FadeIn (1000, dfd.resolve);
return Dfd.promise ();
}

$.when (GetData (), Showdiv ())
. then (function (Ajaxresult, ignoreresultfromshowdiv) {
Console.log (' Fires after BOTH showdiv () and the AJAX request succeed! ');
' Ajaxresult ' is the server ' s response
});

jquery introduces the deferred structure and reconstructs the Ajax, queue, Document.ready, etc. according to the promise mode, and unifies the asynchronous execution mechanism. Then (Ondone, Onfail) appends a callback function to promise, and if the call completes successfully (resolve), the callback function Ondone is executed, and if the call fails (reject), then Onfail is executed. When you can wait on multiple promise objects. The promise is that the callback function can still be registered after the asynchronous execution has started and even after it has ended

Someobj.done (callback). SendRequest () vs. Someobj.sendrequest (). Done (callback)

The callback function is completely equivalent to registering before making an asynchronous call or registering after making an asynchronous call, which reveals that the program expression is never completely accurate and there is always an inherent change dimension. If this intrinsic variability can be effectively exploited, the performance of concurrent programs can be greatly improved.

The concrete implementation of the promise model is simple. Jquery._deferred defines a function queue, which has the following functions:

A. Save the callback function.
B. Perform all the saved functions at resolve or reject time.
C. After it has been implemented, the additional functions will be executed immediately.

Some languages that specialize in distributed computing or parallel computing are built into promise patterns, such as e language, at the language level.

Copy Code code as follows:
def carpromise: = carmaker <-Produce ("Mercedes");
def temperaturepromise: = carpromise <-getenginetemperature ()
...
When (temperaturepromise)-> do (temperature) {
println (' The temperature of the car engine is: $temperature ')
Catch e {
println (' could not get engine temperature, error: $e ')
}



In the E language, &lt;-is the eventually operator, which means it will eventually execute, but not necessarily now. The ordinary Car.moveto (2,3) indicates that immediate execution results. The compiler is responsible for identifying all promise dependencies and automatically implements scheduling.





Extend: Inheritance is not necessary

JS is based on the prototype language, and there is no built-in inheritance mechanism, which has been deeply influenced by the traditional object-oriented education students. But must inheritance be necessary? What can it bring to us? The most simple answer is: code reuse. So, let's first analyze the potential of inheritance as a means of reusing code.

Once there was a concept called "Multiple inheritance," It is a super version of the concept of inheritance, unfortunately later diagnosed as having congenital defects, so that there is an interpretation of the concept of inheritance: Inheritance is the "is a" relationship, a derived object "is a" many of the base class, there must be schizophrenia, So multiple inheritance is not good.

Copy Code code as follows:
Class a{public:void F () {F in A}}
Class b{public:void F () {F in B}}
Class D:public A, b{}

If the D class inherits from A,b two base classes, and the same function f is implemented in Class A and B, is f in Class D the f in a, or F in B, or F in the f+b in a? The emergence of this dilemma actually stems from the fact that the base class A and B of D are in a parallel relationship, they satisfy the commutative law and the binding law, after all, we may not be able to recognize the dependencies between two arbitrary concepts on the conceptual level. But if we relax some of the conceptual aspects of the requirements, more from the operational level to consider the problem of code reuse, you can simply think that b on the basis of a operation, then you can get a linearized result. That is, abandoning the exchange law between A and B only preserves the binding law, extends a, B and extends B,a will be two different results, no longer exist in the interpretation of ambiguity. The so-called Trait (attribute) mechanism in the Scala language actually employs this strategy.

Long after the invention of object-oriented technology, the so-called aspect-oriented programming (AOP), unlike OOP, is the localization and modification technology in the code structure space. AOP's eyes only have classes and methods, and do not know what meaning is. AOP also provides a method of code reuse similar to multiple inheritance, that is mixin. The object is treated as a map that can be opened and then arbitrarily modified, and a set of member variables and methods are injected directly into the object, directly altering its behavior.
The Prototype.js library introduces the Extend function,

Copy Code code as follows:
Object.extend = function (destination, source) {
For (Var property in source) {
Destination[property] = Source[property];
}
return destination;
}

is an overlay operation between maps, but it works, and is also extended in the jquery library. This operation is similar to Mixin, in jquery is the main technical means of code reuse---No inheritance is no big deal.

11. Name Mapping: Everything is Data

Code good, circular judgment must be less. Loop and judgment statements are the basic components of a program, but they are often not found in good code libraries, because the interleaving of these statements blurs the logic of the system and leads to the loss of our thoughts in the pursuit of code tracking. jquery itself through each, extend and other functions have greatly reduced the need for circular statements, for judgment statements, mainly through the mapping table to deal with. The Val () function of jquery, for example, needs to be handled differently for different tags, so define a function mapping table with tagname as key

Copy Code code as follows:
Valhooks: {option: {get:function () {}}}



So there's no need to write anywhere in the program.


Copy Code code as follows:
if (Elm.tagname = = ' OPTION ') {
return ...;
}else if (elm.tagname = = ' TEXTAREA ') {
return ...;
}



Can be handled uniformly


Copy Code code as follows:
(Valhooks[elm.tagname.tolowercase ()] | | | defaulthandler). get (Elm);






The mapping table manages functions as normal data and is widely used in dynamic languages. In particular, the object itself is a container for functions and variables, and can be viewed as a mapping table. One of the techniques used in jquery is to dynamically generate code using name Mapping to form a template-like mechanism. For example, to implement Mywidth and myheight two very similar functions, we don't need


Copy Code code as follows:
JQuery.fn.myWidth = function () {
return parseint (this.style.width,10) + 10;
}

JQuery.fn.myHeight = function () {
return parseint (this.style.height,10) + 10;
}



Instead, you can choose to dynamically generate


Copy Code code as follows:
Jquery.each ([' Width ', ' Height '],function (name) {
jquery.fn[' my ' +name] = function () {
Return parseint (This.style[name.tolowercase ()],10) + 10;
}
});






12. Plug-in mechanism: In fact, I am very simple

jquery's so-called plug-ins are actually added functions on the $.fn, so what is this fn?

Copy Code code as follows:
(function (window,undefined) {


There's another package inside.


var jQuery = (function () {


var jQuery = function (selector, context) {


Return to New JQuery.fn.init (selector, context, rootjquery);


}


....


FN is actually a shorthand for prototype.


Jquery.fn = Jquery.prototype = {


Constructor:jquery,


Init:function (selector, context, Rootjquery) {...}


}





Calling jquery () is the equivalent of new Init (), and the prototype of Init is the prototype of jquery


JQuery.fn.init.prototype = Jquery.fn;





The jquery object returned here has only the most basic functionality, and the following is a series of extend


return jQuery;


})();


...


Exposing jquery as a global object


Window.jquery = window.$ = JQuery;


}) (window);

Obviously, $.fn is actually a shorthand for jquery.prototype.

A stateless plug-in is just a function, very simple.

Copy Code code as follows:
Defining Plug-ins
(function ($) {
$.fn.hoverclass = function (c) {
Return This.hover (
Function () {$ (this). Toggleclass (c);}
);
};
}) (JQuery);

Using Plug-ins
$ (' Li '). Hoverclass (' hover ');






For more complex plug-in development, the JQuery UI provides a widget factory mechanism,


Copy Code code as follows:
$.widget ("Ui.dialog", {
Options: {
Autoopen:true,...
},
_create:function () {...},
_init:function () {
if (This.options.autoOpen) {
This.open ();
}
},
_setoption:function (key, value) {...}
Destroy:function () {...}
});






When you call $ (' #dlg '). dialog (options), the code that actually executes is basically as follows:


Copy Code code as follows:
This.each (function () {
var instance = $.data (This, "dialog");
if (instance) {
Instance.option (Options | | {}). _init ();
} else {
$.data (This, "dialog", New $.ui.dialog (options, this));
}
}



Can see that the first call to $ (' #dlg ') creates a Window object instance and is saved in data, and the _create () and _init () functions are called, and if not the first call, the _init () is invoked on an already existing object instance (). Method. Call $ (' #dlg ') multiple times. Dialog () does not create multiple instances.

Browser sniffer vs. feature detection

Browser sniffing (browser sniffer) used to be a popular technique, such as early jquery

Copy Code code as follows:
Jquery.browser = {
Version: (Useragent.match (/.+ (?: Rv|it|ra|ie) [/:] ([D.] +)/) || [0, ' 0 ']) [1],
Safari:/webkit/.test (useragent),
Opera:/opera/.test (useragent),
Msie:/msie/.test (useragent) &&!/opera/.test (useragent),
Mozilla:/mozilla/.test (useragent) &&!/(Compatible|webkit)/.test (useragent)
};

Can be handled differently for different browsers in specific code

Copy Code code as follows:
if ($.browser.msie) {
Do something
else if ($.browser.opera) {
// ...
}

But as the competition in the browser market upgrades, competitors of the mutual imitation and camouflage caused useragent chaos, and the birth of Chrome, Safari's rise, ie began to speed up to the standard, sniffer has not played a positive role. Feature detection (feature detection), as a finer-grained, more specific means of detection, is becoming a mainstream way of dealing with browser compatibility.

Copy Code code as follows:
Jquery.support = {
IE strips leading whitespace when. InnerHTML is used
Leadingwhitespace: (Div.firstChild.nodeType = = 3),
...
}

It's easier to be compatible with the future, based only on what you actually see, not what you once knew.

Prototype vs. JQuery

Prototype.js is a very ambitious library, its goal is to provide a new experience, the reference to Ruby from the language level of JavaScript to transform, and ultimately really greatly changed the face of JS. $, extends, each, bind ... These familiar concepts are prototype.js introduced into the JS domain. It unbridled in the window global name space to add a variety of concepts, who first occupy the pit who the rational, am momentum. and jquery buckle Soso, holding a more practical concept, the goal is only write less, do more just.

But the fate of those who wait for radical idealists tends to be Chungzhi death first. When Prototype.js's symbolic bind function is absorbed into the ECMAScript standard, it is doomed to decline. The prototype of the original object is changed everywhere, which is the secret secret of Prototype.js, and it is also its dead hole. Especially when it tries to imitate jquery, by element.extend (element) to return to enhance the object, is completely jquery to take to the ditch. Unlike jquery, Prototype.js is always directly modifying the prototype of native objects, while browsers are riddled with bugs, lies, historical baggage and a mix of business conspiracies, and solving problems at the original object level is doomed to tragedy. Performance issues, name collisions, compatibility issues, and so on are all a helper library's ability to solve. Prototype.js's 2.0 version is said to be a big change, I do not know is to break with history, give up compatibility, or continue to struggle, in the gap between survival.

I hope this article will help you with your jquery programming.

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.