Example details jquery's no new build _jquery

Source: Internet
Author: User
Tags closure

No new build of jquery

The core of the jquery framework is to match elements from HTML documents and perform actions on them,

Recall the way to instantiate a jquery object when using jquery:

No new constructs
$ (' #test '). Text (' test ');
 
Of course, you can also use the new
var test = new $ (' #test ');
Test.text (' Test ');

Most people using jquery are constructed directly using the first construction without new, $('') which is a handy place for jquery.

When we use the first method without new constructs, the essence is equivalent new jQuery() , so how does it work within jQuery? Look:

(Function (window, undefined) {
  var
  //...
  jquery = function (selector, context) {
    //The jquery object is actually just the Init constructor ' enhanced '
    ret Urn New JQuery.fn.init (selector, context, rootjquery);
  },
 
  Jquery.fn = Jquery.prototype = {
    init: Function (selector, context, rootjquery) {
      //...
    }
  }
  JQuery.fn.init.prototype = Jquery.fn;
}) (window);

Didn't understand? It's okay, we'll analyze it one step at a A.

function expressions and Function declarations

In ECMAScript, the two most commonly used methods of creating functions are function expressions and function declarations, and the difference between the two is a bit faint, because the ECMA specification is only a bit clear: the function declaration must have an identifier ( Identifier ) (which is the name of the function that everyone often says). And a function expression can omit this designator:

  Functions declaration: Function
Function name (parameter: optional) {function Body}
//function expression: Functions
function name (optional) (parameter: optional) {function Body}

So, as you can see, if you don't declare the function name, it's definitely an expression, but if you declare the function name, how do you decide whether it's a function declaration or a function expression?

ECMAScript is differentiated by context, and if function foo(){} it is part of an assignment expression, it is a function expression,

If function foo(){} it is contained in a function body, or at the top of the program, it is a function declaration.

 function foo () {}//declaration because it is part of the program
 var bar = function foo () {};//expression, because it is part of the assignment expression
 new function bar () {};//Expression, Because it is a new expression
 (function () {
  function bar () {}//declaration, because it is part of the function Body
 }) ();

There is also a function expression that is not very common, is enclosed in parentheses (function foo(){}) , he is an expression because the parentheses () is a grouping operator, its interior can only contain expressions

Then look at the jquery Source:

(Function (window, undefined) {
  /...
}) (window)

The above code structure can be divided into two parts :(function(){window, undefined}) and (window) ,

The 1th () is an expression, and the expression itself is an anonymous function,

So adding (window) behind this expression means executing the anonymous function and passing in the parameter window.

Prototype prototype

Know what a prototype is?

In JavaScript, a prototype is also an object, through which the object's properties are inherited, and the JavaScript object contains an " [[Prototype]]" internal attribute that corresponds to the object's prototype.

The two properties of "prototype" and "__proto__" can sometimes be confused, and "Person.prototype" and "person.__proto__" are completely different.

Here is a brief introduction to "prototype" and "__proto__":

1. For all objects, there is the __proto__ attribute, which is the object's prototype

2. For function objects, in addition to the __proto__ property, there is a prototype property, and when a function is used as a constructor to create an instance, the prototype property value of the function is assigned as a prototype to all object instances (that is, to set the instance's __proto_ Property

function person (name, age) {
  this.name = name;
  This.age = age;
}
Person.prototype.getInfo = function () {
  Console.log (this.name + "is" + This.age + "years old");
Call
var would = new person ("would");
Will.getinfo ()//"'ll is years old"

Closed Bag

Definition of closures:

When an intrinsic function is referenced by a variable outside its external function, a closure is formed.

The function of closure:

Before we understand the effect of closures, let's take a look at the GC mechanism in javascript:

In JavaScript, if an object is no longer referenced, the object is reclaimed by GC, otherwise the object is kept in memory.

In the example above, B is defined in a, so B depends on a, and the external variable C refers to B, so a is indirectly referenced by C,

That is, a is not reclaimed by GC and is kept in memory. To prove our reasoning, look at the following examples:

function A () {
  var count = 0;
  function B () {
    count + +;
    Console.log (count);
  }
  return B;
}
var c = A ();
C ();//1
C ();//2
C ();//3

Count is a variable in a, and its value is changed in B, and every time a function B is executed, the value of Count is incremented by 1 on the original basis. Therefore, the count in a is kept in memory.

This is what closures do, and sometimes we need to define a variable in a module: We want this variable to be stored in memory but not "polluting" the global variable , so we can use the closure to define the module.

Looking at the jquery Source:

(Function (window, undefined) {
  var
  //...
jquery = function (selector, context) {
    //The jquery object is actually just the Init constructor ' enhanced '
    ret Urn New JQuery.fn.init (selector, context, rootjquery);
  },
  Jquery.fn = Jquery.prototype = {
    init: Function (selector, context, rootjquery) {
      //...
    }
  }
  JQuery.fn.init.prototype = Jquery.fn;
}) (window);

We know what a closure is: When an intrinsic function is referenced by a variable outside its external function, a closure is formed.

The init function of Jquery.fn is called by the constructor of jquery, where a closure is formed.
constructor and calling code:

// ...
jquery = function (selector, context) {
    //The jquery object is actually just the Init constructor ' enhanced '
    retur N New JQuery.fn.init (selector, context, rootjquery);
  },

The crux of the matter has come.

How to implement no new build

JavaScript is a functional language, a function can implement classes, and classes are the most basic concepts in object-oriented programming.

var aquery = function (selector, context) {
    //constructor
}
aquery.prototype = {
  //prototype
  name:function () {} ,
  age:function () {}
}
var a = new Aquery ();
A.name ();

It's a routine use, and it's obvious that jquery doesn't play that way.

To do so, jquery is supposed to be a class, then $ () should be an instance of the returned class

In the way jquery was described,

$ (). Ready () 
$ (). Noconflict ()

To do so, jquery is supposed to be a class, then $ () should be an instance of the returned class

So change the code:

var aquery = function (selector, context) {return
    new aquery ();
}
Aquery.prototype = {
  name:function () {},
  age:function () {}
}}

new aQuery(),Although the return is an example, but also can see the obvious problem, dead loop !

So how do you return to a correct instance?

Instance this is only related to prototypes in JavaScript

Then you can create an instance of the jquery class as a factory method and put it into the Aquery.prototye prototype.

var aquery = function (selector, context) {return
    aQuery.prototype.init (selector);
}
Aquery.prototype = {
  Init:function (selector) {return this
    ;
  }
  Name:function () {},
  age:function () {}
}

When executing aQuery() the returned instance:

It is obvious that an instance of the aQuery() class is returned aQuery , so this in Init is actually an instance of the class being pointed to aQuery

Here's the problem. Init's this point is to a aQuery class, and if the init function is also treated as a constructor, then how does the internal this work?

var aquery = function (selector, context) {return
    aQuery.prototype.init (selector);
}
Aquery.prototype = {
  Init:function (selector) {
    this.age = return this
    ;
  },
  name:function () {},< C9/>age:20
}
aquery (). Age//18

Because this only points aQuery to a class, aQuery the age properties can be modified.

This seems to be no problem, in fact, the problem is very big

Why the new jQuery.fn.init?

Look at the following code:

var aquery = function (selector, context) {return
    aQuery.prototype.init (selector);
}
Aquery.prototype = {
  Init:function (selector) {
    if (selector== "a")
      This.age = return this
    ;
  } ,
  name:function () {},
  age:20
}
aquery ("a"). Age//18
aquery ("B"). Age//18

When I call in "a", modify Age=18, and Aquery ("a"). The value of age is 18

But when I passed in "B" and did not change the value of age, I would also like to get the valueof the default age, but Aquery ("B"). The value for age is 18.

Because the age was modified when aquery ("a") was invoked.

In this case there is an error, so you need to design a separate scope to do.

The processing of the jquery framework separator scope

jquery = function (selector, context) {
    //The jquery object is actually just the Init constructor ' enhanced '
    ret Urn New JQuery.fn.init (selector, context, rootjquery);
  },

It is clear that by instance init functions, each time a new instance object is constructed to init separate this and avoid interaction confusion.

Let's revise the code:

var aquery = function (selector, context) {return
    new AQuery.prototype.init (selector);
}
Aquery.prototype = {
  Init:function (selector) {
    if (selector== "a")
      This.age = return this
    ;
  },
  name:function () {},
  age:20
}
aquery ("a"). Age//18
aquery ("B"). Age//undefined

And there's a new problem,

age  :undefined,

name() :Throws an error and cannot find this method, so it's obvious that new is separated from the init jquery class this

How do I access the properties and methods on the jquery class prototype?

Is it possible to isolate scopes and use the scope of the jquery prototype object, and to access jquery's prototype objects in the return instance?

Key points to achieve

Give the INIT function the JQuery prototype for later instantiation
jQuery.fn.init.prototype = Jquery.fn;

Let's change it again:

var aquery = function (selector, context) {return
    new AQuery.prototype.init (selector);
}
Aquery.prototype = {
  Init:function (selector) {
    if (selector== "a")
      This.age = return this
    ;
  },
  name:function () {return
     to age;
  },
  age:20
}
aQuery.prototype.init.prototype = Aquery.prototype; 

Aquery ("a"). Age//18
aquery ("B"). Age//20
aquery ("a"). Name ()  //20

Finally look at the jquery Source:

(Function (window, undefined) {
  var
  //...
jquery = function (selector, context) {
    //The jquery object is actually just the Init constructor ' enhanced '
    ret Urn New JQuery.fn.init (selector, context, rootjquery);
  },
  Jquery.fn = Jquery.prototype = {
    init: Function (selector, context, rootjquery) {
      //...
    }
  }
  JQuery.fn.init.prototype = Jquery.fn;
}) (window);

Are you clear?

Ha ha ~ ~ ~

In a nutshell, two words:

Most people at jQuery.fn.init.prototype = jQuery.fn the beginning of this sentence will be the card Lord, is very puzzled. But this is really a wonderful thing about jQuery. It is very important to understand these sentences, to point out the points:

1 The first thing to be clear, the use $('xxx') of this instantiation method, its internal call is return new jQuery.fn.init(selector, context, rootjQuery) this sentence, that is, the construction of an instance is given to the jQuery.fn.init() method to complete.

2 The jQuery.fn.init prototype property is set to jQuery.fn , then the prototype object that uses the new jQuery.fn.init() generated object is jQuery.fn , so the function mounted to jQuery.fn the above is equivalent to being mounted jQuery.fn.init() on the generated JQuery object, all using new jQuery.fn.init() The generated object can also access jQuery.fn all of the prototype methods on.

3) is the instantiation method exists such a chain of relationships

1.jquery.fn.init.prototype = Jquery.fn = Jquery.prototype;

2.new JQuery.fn.init () is equivalent to new jQuery ();

3.jQuery () returns the new JQuery.fn.init (), while var obj = new jquery (), so these 2 are equivalent, so we can instantiate the JQuery object without new.

Summarize

This is the full content of jquery's no new build, and I hope this article will help you learn jquery. And please continue to support the cloud-dwelling community.

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.