2

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?

john blair
  • 312
  • 3
  • 10

1 Answers1

1

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()
charlietfl
  • 164,229
  • 13
  • 110
  • 143
  • Not an easy question to answer since it's not really clear what to focus on to help you sort out confusion – charlietfl Jan 30 '18 at 12:57
  • Thanks for the reply - sorry the site timed me out while trying to clarify my comment. You said: "It is used extensively in the core to add properties to the jQuery object itself". My problem is jQuery is not an instantiated object in the traditional sense but a function (which i know is a special type of object) ... so where/how is the instance created of the object that "this" refers to inside of the extend function when only 1 parameter is supplied? This is the first time I've seen a function extended in this manner. – john blair Jan 30 '18 at 13:06
  • Look at the simple object example at bottom of my answer. It is doing exact same thing when jQuery.extend() is used internally. `target=this` is same as `target=jQuery` due to calling context – charlietfl Jan 30 '18 at 13:09
  • I totally understand your obj code example as obj is instantiated as an object. if you changed your example to obj = function(){ that would reflect my problem as i would no longer see where the instance of this is created in your log function example. Thank you. – john blair Jan 30 '18 at 13:14
  • But a function is an object. Same thing defined as function: https://jsfiddle.net/v9vunmkn/ – charlietfl Jan 30 '18 at 13:16
  • (function() { var jb = function(){} jb.func = function (){ alert("jb.func this is " + typeof this) } jb.func(); })(); this is display as a function not an object and i always thought this has to be an object instance to add to it. – john blair Jan 30 '18 at 13:30
  • Admit it's not very intuitive but I think it should solve your confusion a bit now...right? Also might help [how-does-the-this-keyword-work](https://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – charlietfl Jan 30 '18 at 13:36
  • That was a useful article on this ... very helpful, thanksl. I've accepted your answer but don' have enough reputation for it to show. It seems in javascript a function is an instantiated object - i guess this is very different to my usual c# understanding of when objects get instantiated. – john blair Jan 30 '18 at 14:01
  • javascript does have some quirks. Have to realize the whole language was originally created in just a few days back in early NetScape days but once you understand the quirks is still very powerful language. Also have to realize that jQuery originated at a time that different browsers had inconsistent behaviors also. That has normalized a lot since then but jQuery evolved to normalize those inconsistencies – charlietfl Jan 30 '18 at 14:03