Not needing brackets when not passing any arguments - javascript

I am creating a function with this line:
window.Spark = window.$ = function(selector, context) { ... };
But I am having a problem (obviously), if I call a function like this $('p').content('Hi!'); then everything works great because I am treating $ like a function. However, when I run a function like this $.ajax('get', 'example.txt'); I get this error $.ajax is not a function. This is because I am not including the brackets. Does anyone know a way around this? I saw in the jQuery source that they have a function within a function. Is this the sort of thing I need?
Thanks for any help you can offer.

I assume by brackets you mean parentheses.
In jQuery, $ is a function with properties.
You can replicate this type of behavior simply by assigning properties to $:
window.Spark = window.$ = function(selector, context) { ... };
$.ajax = function(method, url) { ... };

Functions are first class citizens in JavaScript, i.e. you may treat them like objects are being treated in OOP. It's possible to assign properties to them and those properties may be functions in turn.
So, $.ajax is really nothing else then the property ajax that's a "member" of the function (object) $ that happens to be a function.
So long.

If you put a function within a function it's local to the outer function, so it's not possible to call it from outside the function.
A function in Javascript is an object like any other, so you can add properties to it, and the property can be a function:
var $ = function() { alert("1"); };
$.ajax = function() { alert("2"); };
$(); // shows "1"
$.ajax(); // shows "2"

Um.... $.ajax needs to be a function to be called like that. So either define the 'ajax' function or don't use it.

I'm pretty sure it has nothing to do with "not including the brackets," whatever that means. In jQuery, the identifier $ represents a function object that has several attributes. One of these attributes is ajax, which contains a function that performs an AJAX call. Just because you call your own function $ doesn't mean it automagically gets the functionality of jQuery. If you want $.ajax to be a function, you'll need to define it.

Related

What is the meaning of the "t" in the code and what does t(window) mean?

I am trying to learn jquery/javascript by looking at the source code of some websites. I am a bit unsure about the syntax used there:
!function(t) {
"use strict";
function e() {
var e = parseInt(t(window).scrollTop()),
n = 10;
e > n ? a.addClass("new-class") : (a.removeClass("new-class"), t(".sclass").removeClass("fclass"))
}
//...more codes...
}(jQuery),
I just don't really get what exactly is the meaning of that t there. Is it "this" or just any event object? and what does t(window) means? I thought it should be something like t.window? Since t is not a function.
Thanks!
Saldtch
t is a reference to the jQuery object within the scope of that function. Notice how the function is called:
!function (t) {
// "t" is the jQuery object
}(jQuery);
The function is defined and then immediately invoked with the parameter jQuery. So when the function is invoked, that parameter being passed is stored in the variable t. You could name it anything, really:
!function (foo) {
// "foo" is the jQuery object
}(jQuery);
The function is defined inline, so it doesn't have a name, and immediatley gets called with param jQuery. "t" is the formal parameter of the inline function, which gets resolved with the concrete parameter "jQuery".
Shortly, variable t refers to the jQuery object (or whatever jQuery variable holds).
Insert this code in the function e():
console.log(t === jQuery);
You will assert that t is jQuery alias indeed in that function.
That's equivalent to:
function x(t) {
//code in here
}
x(jQuery);
Therefore t is a local reference in the function to jQuery.
And, t(window) is equivalent to jQuery(window) ... and by extension $(window).
As already mentioned above, t equals to the jquery object in this case. t(window) means, wrap the window object with the jquery object, so after wrapping it, i can call jquery methods on it. I'm sure you are already familiar with jquery's $(selector) method, which does the same (fair enough).
So, $('#product') should get the DOM element with id "product" and wrap it inside a jquery object.
Example:
var myProduct = document.querySelector('#product');
myProduct.attr('id'); // error, myProduct doesn't have method attr() because it is not a jquery "instance"
$(myProduct).attr(id); // product, we wrapped the item in a jquery object
Since jquery is named as t in your example, t(window) is wrapping the window object in jquery. The window object normally doesn't have a scrollTop() method defined on it.

How can jQuery seemingly be both an object and a method invoked by an object?

There's a workaround function for an API object called unsafeWindow for browsers that don't support it (via this person's github)
var unsafeWindow = (function() {
var e1 = document.createElement('p')
e1.setAttribute('onclick', 'return window;');
return e1.onclick();
})();
// If the current document uses a JavaScript library, you can use it in
// your user script like this:
console.log(unsafeWindow.jQuery);
If unsafeWindow is an object (or in this case a function designed to mimic the object), how can it be used like $ = unsafeWindow.jQuery? I know this is how you map the function to the $ instead of the $ being a simple jQuery alias, but I'm just confused as to why, since I thought jQuery itself was an object, and is being invoked here like one would a method.
Edit: Thank you for your answers, I wish I could "check mark" all of you, thanks for the help!
In javascript, functions are objects!
Don't let the . blindfold you. object.something is getting the property something which could be anything (function, variable, object, value..), while object.something() is applying the method something
When you do $ = unsafeWindow.jQuery you are assigning the jQuery object to $ like you rightly pointed out. You are not invoking any function. Invoking a function in javascript involves adding a parenthesis () at the end.
Jquery is a constructor function with methods attached. When used as $.each(), you are just calling the method each() that is attached to the function (object). When you use $(), it calls an internal new jQuery() and returns it, giving you access to it's prototype methods.

jQuery type class structure

So I was wondering if anyone could help me understand how the jQuery 'class' works. From what I can tell, it works like a static class like such:
if(!$) { var $ = new function(){} }
I think..
Now, what is confusing to me, is how you can call a method both with OR without arguments like such:
$("a").removeClass("test");
$.get('myhtmlpage.html', myCallBack);
I am assuming passing that argument simply returns document.getElementById(argument);
But how? How is this argument passed into the class after the fact like this? also, is this some result of method chaining?
Anything info to help me understand what is going on would be great! Thanks.
I'm working with the jQuery source here, so you can look at it as well.
The $ function isn't explicitly defined, but instead linked to the jQuery object:
window.$ = jQuery;
The jQuery object is defined like so:
jQuery.fn = jQuery.prototype = {
constructor: jQuery,
init: function( selector, context, rootjQuery ) {
The init: function( selector part handles $('foo') cases.
If no parameters are given, the another function is used:
get: function( num ) {
Variables in JavaScript can contain $. for example foo and $foo are different variables. Naturally $ is a valid object.
Next thing worth noting is that in JavaScript everything is a class. Function is a class too, so your function might have methods too.
$ <-- this is a function with methods.
$('a') <-- this executes that function which does something and return $ again.
$.get() <-- this calls method of that jQuery function.
$('a').get() <-- this executes function with argument a which returns $ again then you grab it's method and execute that again.
When $('a') is called, not the exact same $ is returned, it would contain some extra information about the selector you used.
My final note is that when you call $(x); where x is a function, then it's used as a shortcut to registering on-document-ready call-back.

Help understanding Javascript unusual function declaration syntax

I have am trying to understand the Javascript/jQuery behind ColorBox. Some forms of syntax are a bit hard to search on Google as they are a bit lengthy to describe. I am having trouble understanding the following line:
publicMethod = $.fn[colorbox] = $[colorbox] = function (options, callback) {
So I assume a new function called publicMethod is being created, but how do we but I don't really understand anything beyond the first equals symbol ("=").
A normal function declaration would look like this:
function publicMethod(options, callback) {
So if anybody could help me understanding the syntax I would greatly appreciate it.
In:
$.fn[colorbox]
$ is an unhelpfully non-descriptive variable name. It contains an object.
$.fn access the fn property of that object.
fn[colorbox] accesses the property of that object which a name that matches the string stored in colorbox
But the right hand side of and = is defined first, So before it assigns that value to publicMethod it assigns the value of $[colorbox] to $.fn[colorbox].
… and before it does that it assigns (to there) a function.
function () {} defines an anonymous function and passes it left (so it gets stored in whatever is on the other side of =)
In JavaScript, functions are on the same level as other objects - you can assign them to variables, and pass them as parameters.
Normally, you would declare a function in this way:
function SomeFunc(arg1, arg2) { /* etc etc */ }
An equivalient way would to be:
var SomeFunc = function(arg1, arg2) { /* etc, etc */ }
...because, as above, functions themselves are values that may be assigned or passed.
Many libraries will accept functions as arguments to their own functions, running the passed function at a time which suits them (or passing them on elsewhere, a la any other variable). Often this is for callbacks. When passing functions as arguments, there isn't really a need to give them a name of their own, thus the following does the job:
SomeLibrary.doSomethingThenCallback(function(arg1, arg2) {
// the doSomethingThenCallback function will decide when, if ever,
// to run this, or pass it on somewhere else, or whatever else would
// be done with any other argument value.
});
This function publicMethod(options, callback) {} is nearly but not completely the same as var publicMethod = function(){options, callback}. In first case you create function named publicMethod and in the second you create anonymous function and assign it to publicMethod variable. Other to assignations just save this function for the further use as API method.

What does (function($) {})(jQuery); mean?

I am just starting out with writing jQuery plugins. I wrote three small plugins but I have been simply copying the line into all my plugins without actually knowing what it means. Can someone tell me a little more about these? Perhaps an explanation will come in handy someday when writing a framework :)
What does this do? (I know it extends jQuery somehow but is there anything else interesting to know about this)
(function($) {
})(jQuery);
What is the difference between the following two ways of writing a plugin:
Type 1:
(function($) {
$.fn.jPluginName = {
},
$.fn.jPluginName.defaults = {
}
})(jQuery);
Type 2:
(function($) {
$.jPluginName = {
}
})(jQuery);
Type 3:
(function($){
//Attach this new method to jQuery
$.fn.extend({
var defaults = {
}
var options = $.extend(defaults, options);
//This is where you write your plugin's name
pluginname: function() {
//Iterate over the current set of matched elements
return this.each(function() {
//code to be inserted here
});
}
});
})(jQuery);
I could be way off here and maybe all mean the same thing. I am confused. In some cases, this doesn't seem to be working in a plugin that I was writing using Type 1. So far, Type 3 seems the most elegant to me but I'd like to know about the others as well.
Firstly, a code block that looks like (function(){})() is merely a function that is executed in place. Let's break it down a little.
1. (
2. function(){}
3. )
4. ()
Line 2 is a plain function, wrapped in parenthesis to tell the runtime to return the function to the parent scope, once it's returned the function is executed using line 4, maybe reading through these steps will help
1. function(){ .. }
2. (1)
3. 2()
You can see that 1 is the declaration, 2 is returning the function and 3 is just executing the function.
An example of how it would be used.
(function(doc){
doc.location = '/';
})(document);//This is passed into the function above
As for the other questions about the plugins:
Type 1: This is not a actually a plugin, it's an object passed as a function, as plugins tend to be functions.
Type 2: This is again not a plugin as it does not extend the $.fn object. It's just an extenstion of the jQuery core, although the outcome is the same. This is if you want to add traversing functions such as toArray and so on.
Type 3: This is the best method to add a plugin, the extended prototype of jQuery takes an object holding your plugin name and function and adds it to the plugin library for you.
At the most basic level, something of the form (function(){...})() is a function literal that is executed immediately. What this means is that you have defined a function and you are calling it immediately.
This form is useful for information hiding and encapsulation since anything you define inside that function remains local to that function and inaccessible from the outside world (unless you specifically expose it - usually via a returned object literal).
A variation of this basic form is what you see in jQuery plugins (or in this module pattern in general). Hence:
(function($) {
...
})(jQuery);
Which means you're passing in a reference to the actual jQuery object, but it's known as $ within the scope of the function literal.
Type 1 isn't really a plugin. You're simply assigning an object literal to jQuery.fn. Typically you assign a function to jQuery.fn as plugins are usually just functions.
Type 2 is similar to Type 1; you aren't really creating a plugin here. You're simply adding an object literal to jQuery.fn.
Type 3 is a plugin, but it's not the best or easiest way to create one.
To understand more about this, take a look at this similar question and answer. Also, this page goes into some detail about authoring plugins.
A little help:
// an anonymous function
(function () { console.log('allo') });
// a self invoked anonymous function
(function () { console.log('allo') })();
// a self invoked anonymous function with a parameter called "$"
var jQuery = 'I\'m not jQuery.';
(function ($) { console.log($) })(jQuery);
Just small addition to explanation
This structure (function() {})(); is called IIFE (Immediately Invoked Function Expression), it will be executed immediately, when the interpreter will reach this line. So when you're writing these rows:
(function($) {
// do something
})(jQuery);
this means, that the interpreter will invoke the function immediately, and will pass jQuery as a parameter, which will be used inside the function as $.
Actually, this example helped me to understand what does (function($) {})(jQuery); mean.
Consider this:
// Clousure declaration (aka anonymous function)
var f = function(x) { return x*x; };
// And use of it
console.log( f(2) ); // Gives: 4
// An inline version (immediately invoked)
console.log( (function(x) { return x*x; })(2) ); // Gives: 4
And now consider this:
jQuery is a variable holding jQuery object.
$ is a variable
name like any other (a, $b, a$b etc.) and it doesn't have any
special meaning like in PHP.
Knowing that we can take another look at our example:
var $f = function($) { return $*$; };
var jQuery = 2;
console.log( $f(jQuery) ); // Gives: 4
// An inline version (immediately invoked)
console.log( (function($) { return $*$; })(jQuery) ); // Gives: 4
Type 3, in order to work would have to look like this:
(function($){
//Attach this new method to jQuery
$.fn.extend({
//This is where you write your plugin's name
'pluginname': function(_options) {
// Put defaults inline, no need for another variable...
var options = $.extend({
'defaults': "go here..."
}, _options);
//Iterate over the current set of matched elements
return this.each(function() {
//code to be inserted here
});
}
});
})(jQuery);
I am unsure why someone would use extend over just directly setting the property in the jQuery prototype, it is doing the same exact thing only in more operations and more clutter.

Categories