In my previous blog, a shoes asked about XQuery. FN. init. prototype = XQuery. FN; the purpose of writing. This problem was also encountered when I copied jquery. At first, I did not add this method. In firebug, the method console. log (XQuery (''). XQuery); the output is undefined, which indicates that the XQuery attribute is not defined at all. The XQuery object I constructed is only retained in the XQuery. FN. the attributes in Init (selector, context); are tested as follows:
XQuery. fn = XQuery. prototype = {init: function () {return this;}, tempquery: '1. 0.1 ', Length: 23, size: function () {return this. length ;}}; console. log (XQuery (). tempquery); // undefinedconsole. log (XQuery (). length); // undefinedconsole. log (XQuery (). size (); // error: XQuery (). size is not a function
So what is the role of XQuery. FN. init. Prototype = XQuery. FN? I did the following series of tests:
Test 1:Code:
VaR XQuery = function (selector, context) {return New XQuery. FN. INIT (selector, context );}
This is to build an object using the factory mode in Javascript, but this factory is quite special, which makes people first think it is an iterative call factory mode, so I wrote the following test code:
VaR XQuery = function () {return New tempquery () ;}; var tempquery = function () {}; tempquery. prototype = {tempquery: '1. 0.1 ', Length: 4, size: function () {return this. length ;}}; console. log (XQuery (). tempquery); // 1.0.1lele.log (XQuery (). length); // 4console. log (XQuery (). size (); // 4console. log (XQuery () instanceof XQuery); // false
Here I set up another object tempquery and initialized the attributes of the prototype chain of tempquery. Every time I call XQuery (), it is the tempquery object that is used as the return value of the XQuery constructor. If you do this, there will be disadvantages of the factory mode in javascript: 1. duplicate similar objects will be generated, resulting in a waste of system resources; 2. XQuery object recognition problems (for example, console. log (XQuery () instanceof XQuery); // false ).
To solve these problems, the XQuery constructor should be to construct itself, instead of being a new object every time the constructor constructs itself. This approach can avoid the defect of the Javascript factory model, so I did the following test again.
Test 2:
VaR XQuery = function () {returnnew XQuery (); // too much recursion new XQuery (); // too much recursion, infinite recursive call}; XQuery. prototype = {tempquery: '1. 0.1 ', Length: 8, size: function () {return this. length ;}}; console. log (XQuery (). tempquery); console. log (XQuery (). length); console. log (XQuery (). size (); console. log (XQuery () instanceof XQuery );
The final result is a too much recursion new XQuery (); // too much recursion, an error of infinite recursive calling, that is, memory overflow. This is really an idiot. If it is not for the purpose of verifying the results, I will not write such obvious recursive call code.
So there is something better to write. If so, let's look at the jquery source code and find that it uses the prototype chain to construct the XQuery object. Therefore, the following test code is available:
Test 3:
VaR XQuery = function () {return New XQuery. prototype. init () ;}; XQuery. prototype = {init: function () {return this;}, tempquery: '1. 0.1 ', Length: 8, size: function () {return this. length ;}}; console. log (XQuery (). tempquery); // undefinedconsole. log (XQuery (). length); // undefinedconsole. log (XQuery () instanceof XQuery); // falseconsole. log (XQuery (). size (); // XQuery (). size is not a function
In this way, no memory overflow error is reported, but it does not achieve the expected results of XQuery (). tempquery and XQuery. the length is undefined, and the XQuery () type is not XQuery, And the size () has not been defined.ArticleI didn't write XQuery. FN. init. Prototype = XQuery. FN;.) Why is there such a result? In fact, it is very easy to understand this result from the theory of JavaScript objects. Cause analysis:
We know that all the other basic types in Javascript except string and Boolean are objects, and the object name is only the address of the object in the stack memory, in other words, this object is referenced. In fact, weProgramReturn new XQuery. prototype. init (); this only calls XQuery. prototype. init (); the referenced object has no attributes in other objects, that is, the attributes in the Code:
Size: function () {return this. length ;}
It has not been called yet, so we see the error of size is not a function. I am confused. In fact, we need to know a knowledge in Javascript. Javascript is a scripting language, which is compiled with C and Java, the operation is very different. In JavaScript, if we define a function, for example:
VaR FTN = function () {alert ('Hello World ');}
When a page is loaded, the javascript interpreter in the browser only contains the FTN variable. This process is called the pre-Compilation of javasript. At this time, FTN = undefined. When we are new FTN, that is, when we run JS Code, the javascript interpreter first compiles and then executes, while the return New XQuery. prototype. init (); only the init () object is run, and the size is not run, so the running result is the error of size is not a function.
To solve this problem, we only need to return New XQuery. prototype. init (); at the same time, let the XQuery. other prototype Code also runs. Isn't the above problem solved?
If so, I did the fourth test.
Test 4:
VaR XQuery = function () {return New XQuery. prototype. init () ;}; XQuery. prototype = {init: function () {return this;}, tempquery: '1. 0.1 ', Length: 8, size: function () {return this. length ;}}; XQuery. prototype. init. prototype = XQuery. prototype; console. log (XQuery (). tempquery); // 1.0.1lele.log (XQuery (). length); // 8console. log (XQuery () instanceof XQuery); // trueconsole. log (XQuery (). size (); // 8
Haha, this is not the effect of jquery. I direct the prototype chain of the corresponding object referenced by XQuery. Prototype. init to XQuery. prototype, and then construct new XQuery. Prototype. INIT ();
When XQuery. prototype is also constructed, how can I modify the same attributes as init in init?
Test 5:
VaR XQuery = function () {return New XQuery. prototype. init () ;}; XQuery. prototype = {init: function () {This. length = 10001; this. tempquery = '1. 6.1 '; return this;}, tempquery:' 1. 0.1 ', Length: 8, size: function () {return this. length ;}}; XQuery. prototype. init. prototype = XQuery. prototype;
Result:
Console. log (XQuery (). tempquery); // 1.6.1lele.log (XQuery (). length); // 10001console. log (XQuery () instanceof XQuery); // trueconsole. log (XQuery (). size (); // 10001
This indicates that this pointer points to the same XQuery object, indicating that XQuery. prototype is also built. However, the above method seems to be different from jquery, but the effect is the same.
Jquery in jquery. FN is nothing to say, But jquery developers think that jquery. prototype is too long. FN as jquery. the prototype alias. Below I modify the code to the jquery style. The final code is as follows:
VaR XQuery = function () {return New XQuery. prototype. init () ;}; XQuery. fn = XQuery. prototype = {init: function () {This. length = 10001; this. tempquery = '1. 6.1 '; return this;}, tempquery:' 1. 0.1 ', Length: 8, size: function () {return this. length ;}}; XQuery. FN. init. prototype = XQuery. FN; console. log (XQuery (). tempquery); // 1.6.1lele.log (XQuery (). length); // 10001console. log (XQuery () instanceof XQuery); // trueconsole. log (XQuery (). size (); // 10001
To sum up, I would like to say that this is the core of the jquery architecture. After writing it, I find that it is not actually the case. So here we just say that the code in the jquery source code is very skillful, in my next blog, I plan to pause the analysis of jquery source code. In some basic knowledge systems, JavaScript is a language that is often overlooked. It has many unconventional and strange syntaxes, maybe all of them are clear, but from time to time, it is quite helpful to know new things.