I am creating an AJAX API for a web service and I want to be able to call jQuery-like accessors.
jQuery seems to be able to execute ‘jQuery’ as a function, but also use it to directly access the object that is the result of the function EG:
jQuery();
jQuery.each({});
This is the trick that I can’t seem to pull off:
myAPI('foo'); //output: 'foo'
myAPI('foo').changeBar(); //output: 'foo' 1
myAPI.changeBar(); //Error: not a function
I have seen the answers to similar questions, which are helpful, but don’t really answer my question.
#8734115 – Really interesting, but you can’t access the methods that were set by f.prototype.
#2953314 – Uses Multiple operations to create object instead of a single function.
here is my code:
(function(window) {
var h = function(foo) {
// The h object is actually just the init constructor 'enhanced'
return new h.fn.init(foo);
};
/**
* Methods defined at protoype.
*/
h.fn = h.prototype = {
constructor: h,
init: function(foo) {
console.log(foo);
return this;
},
splice : function () {},
length : 0,
bar : 0,
changeBar : function() {
this.bar++;
return this.bar;
}
};
h.fn.init.prototype = h.fn;
//Publish
window.myAPI =h;
}( window));
I’m sure I’m missing something simple 🙁
What jQuery is doing there is using
jQueryas both a function and as a pseudo-namespace. That is, you can calljQuery:var divs = jQuery("div");and you can use properties on it, e.g.:jQuery.each(...);.This is possible because in JavaScript, functions are first-class objects, and so you can add arbitrary properties to them:
That’s literally all there is to it.
Within the call to
bar,thiswill be thefoofunction (becausethisis determined entirely by how a function is called, not where it’s defined). jQuery doesn’t usethisto refer to itself (usually it usesthisto refer to DOM elements, sometimes to other things like array elements; when referring to itself, since it’s a single thing, it just usesjQuery).Now, you might want to ensure that your functions have proper names (whereas the function I assigned to
barabove is anonymous — the property has a name, but the function does not). In that case, you might get into the module pattern:That pattern also has the advantage that you can have private data and functions held within the scoping function (the big anonymous function that wraps everything else) that only your code can use.
In your code, you’re assigning things to the
prototypeproperty of the function. That only comes into play when the function is called as a constructor function (e.g., vianew). When you do that, the object created bynewreceives the function’sprototypeproperty as its underlying prototype. But that’s a completely different thing, unrelated to what jQuery does where it’s both a function and a pseudo-namespace.