jQuery is defined as a function
jQuery.extend
is defined as a function property and is itself a function - but is not available to any this
scope.
jQuery.fn.extend
is defined as a prototype object property - so is available within the scope of this
Why define jQuery.extend
in this way as jQuery is not actually an object its a function?
For reference the confusing line of code is:
jQuery.extend = jQuery.fn.extend = function() {...}
noting that
jQuery.fn === jQuery.prototype
which is an object {} and jQuery is a function
This means using jQuery.extend
directly there is no object instantiated for a this context.
I don't see anywhere in the jQuery code where jQuery is set to a new jQuery() instance . In the jQuery constuctor the only instance I see returned is for the init function i.e. return new jQuery.fn.init().
At runtime within the document ready function if you check what type of object jQuery and $ are you will see it is still a function (not an object instance). So whenever jQuery.extend is called with one parameter, the function will try to extend jQuery itself but by using "this" as the target object i.e. code snippet
// Extend jQuery itself if only one argument is passed
if (i === length) {
target = this;
i--;
}
Now in my tests "this" within the extend function is referring to the jQuery function not an object instance so the function is being extended with extra "properties" off of the function. What I'm not understanding is how you can add/extend object properties to the function when it has not been instantiated with any new instance creation?
jQuery.extend
is really just a utility function used to merge objects. It is similar to the more modern Object.assign()
that didn't exist when jQuery library was started
It is used extensively in the core to add properties to the jQuery object itself but is also available for developer to use to merge their own objects using $.extend(target [, object1 ] [, objectN ] )
Since it is used as a static method there is no new
instance.
There are several other jQuery methods that are used both internally as utility functions and are exposed publicly such as jQuery.each
and jQuery.fn.each
which precedes the modern Array#forEach()
but can also be used to iterate objects
Using it in your own code allows you to do
var a = {x:1},
b = {y:2},
res = $.extend({}, a, b)
console.log(res) // new object { "x": 1, "y": 2}
console.log(a) // unmodified - still {x:1}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
As for section you noted where target = this;
that can be explained using a simple object that has a function as property. this
in the function is the object itself due to calling context.
When called within the source core the object is jQuery
Simple object example:
var obj = function() {};
obj.x = 1;
obj.log = function() {
// `this` is `obj`
console.log('this.x = ', this.x)
}
obj.log()