Assign Properties to a Function. For Real

Did you know in JavaScript you can assign properties to a function? No not variables and this isn’t a scope discussion. Your function when read is literally an object that has a function prototype. The function prototype has some methods like apply, call, etc. If you look at the object in Firefox console yourself you can see how it’s an infinite sea of inherited constructors and prototypes reaching forever. Anyway the idea is from what I understand, JS creates an object in the identifier, prototypes function. When you use your function call syntax, it is using these methods to reference your function block statement probably stored somewhere else, because your code isn’t stored in the object.

function a(){ console.log("Test"); }

a.test = "Test";
3 Likes

As is often said, “Everything in JavaScript is an object.” It’s a bit hyperbolic, but there is some truth to it.

An example of a function that uses this technique is the jQuery (or $) object. It’s a function that has properties such as getJSON and ajax.

jQuery is just an object constructor (a class), it isn’t really attaching methods to a function in the way described (though you could argue as everything is an object it all works in the same way, but it’s a stretch). All the jQuery functions are just methods on the prototype of the jQuery object.

// jQuery is just function that creates an object, i.e. a class.
// calling it creates a new object constructed using the
// `fn` prototype method (aliased as `jQuery.fn`)
var jQuery = function(selector, context) {
  return new jQuery.fn.init(selector, context);
};

// the main method, just an alias of jQuery.prototype
jQuery.fn = jQuery.prototype = {
  constructor: jQuery;

  // core internal functions here
};

// jQuery.prototype.init (aliased as `fn.init`) is the main entry point,
// it creates the jQuery object that wraps selected elements
jQuery.fn.init = function(selector, context) {
  // core functions to select elements here
}

which is kinda basically like (note following is non-functional, just as example)

class joeQuery {
  init(selector) {
    return document.querySelectorAll(selector);
  }
}

const $ = function(selector) {
  return new joeQuery.prototype.init(selector);
};