How can I create jQuery like method chaining while maintaining a namespace? - javascript

I've looked at various answers on SO that answer similar questions, but none have really answered what I'm looking for. Examples here:
jQuery prototype and constructor function chaining
How does basic object/function chaining work in javascript?
I'd like to be able to chain methods from a function, but also use that function as a namespace. You can use the jquery object as a function like so:
$('selector');
but you can also reach methods straight from the $ variable, like so:
$.ajax(
How is this achieved? I've tried looking into the jquery source but it's near impossible to follow.

In Javascript functions are first-class objects. In particular, they are objects.
var greet = function(name) {console.log("Hello, " + name + "!"); };
greet.lang = "English";
Is legal. Then the following are both valid:
greet("Alice"); // prints Hello, Alice!
console.log(greet.lang); // prints English
I don't think it's accurate to call $(...) a constructor. In Javascript the line between constructor and function is blurred, but usually I would say a constructor is used with new, and, by convention, starts with a Capital letter. $ is simply an object, and in particular one that is a function, so may be called, and has other properties that may be accessed.
I also wouldn't call $, or in my example greet, a namespace. You may be thinking of the package syntax in Java where com.mycompany.util.StringFunctions would have the package/namespace com.mycompany.util, or in C++ where this might be written as MyCompany::Util::StringFunctions. Javascript doesn't quite have this concept, but in more or less any OO language it can be simulated with objects, as above. I would say $ just feels like it's a namespace because it's a rather huge library, but it's a huge library that is implemented as one object that is also a function, with many properties.

Just try this:
var foo = function (){
alert ("I'm a function beep beep");
};
foo.bar = "This is a string";
foo.otherFoo = function (param) {
alert ("I'm also a function blup blup"+param);
};
Then you can call the first function foo(), the variable foo.baror the second function with a value foo.otherFoo(" and more blup.")

Related

how is jQuery able to call an object $ [duplicate]

This question already has answers here:
How does jQuery makes the jQuery object both a function and an object property?
(3 answers)
Closed 7 years ago.
If $ is an object then how is jQuery able to call it with parenthesis (), like $('#MYdIV'). That is my first and most important question.
I am trying to learn design patterns, and underlaying mechanisms of creating an object. So I want to make library that when user type myLibrary({option1:true}); he would be able to instantiate an object without using keyword new.Just like jquery and this: https://github.com/bendc/animateplus/blob/master/animate.js
In this example he is not using keyword new nor this. He is just creating IIFE animate which returns another function with the same name. I don't know how is he able to do that. Is animate bound to global object?
jQuery or $ is just a function. Consider the following example which produces an object with the similar behavior.
Of course, jQuery has the much more complex and smart structure, this is just an example:
var not$ = function(o) {
var result = document.querySelectorAll(o);
result.customInnerText = function(text) {
if (text === undefined) {
return document.querySelector(o).innerText;
} else {
document.querySelector(o).innerText = text;
}
};
result.customClickHandler = function(callback) {
document.querySelector(o).addEventListener('click', callback);
};
return result;
};
not$.customConsoleLog = function(text) {
console.log(text);
};
not$("a").customClickHandler(function() {
var exampleText = not$("#title").customInnerText();
not$("#text").customInnerText(exampleText + "It works!");
not$.customConsoleLog(not$("p").length);
not$.customConsoleLog(not$("p")[0]);
});
Click me!
<p id="title">Example:</p>
<p id="text">Check!</p>
First a few terms:
a primitive is one of the following: string, number, boolean, null, undefined, symbol
An object is essentially any kind of thing that's not a primitve in Javascript. If it's a thing you want to use or manipulate, it's an object.
A function is a particular type of object that can be used to run javascript. This can be called by using the syntax function()
A constructor is just a function. It's a function which is intended to be called with the new keyword, as in new Thing(). Note the capital letter - that's convention.
So we can see that JQuery uses a function, not a constructor function. Specifically, if you look into the source code we'll find something like $ = function() {...}
And that's basically it - they define a global variable called $ and define it to be a function that can be used. Of course, since functions are objects, you can also do things like $.randomNumber = 4 without problems, and it won't affect JQuery in the slightest.
So if you're wanting to do something similar, you'll want to define your own global variable and set it as a function - just be aware of what's already taken - i.e. don't use $ or _ or whatever.
(1) $ is not an object, but a function.
console.log(typeof $);
// function
What might be confusing here - and this is just a guess - is that you can access properties on the $ variable, e.g. $.extend or $.fn (used when writing your own jQuery plugins). This is normal, as functions can have properties themselves. The ECMAScript specifications allow that.
(2) Constructor functions can be used to create new objects, but are not required. You can just used object literals, and that works just as well. As pointed out by #Jeff in the other answer, a function invoked with new makes it a constructor function. Otherwise, there is no difference in the syntax. It is up to you to pick whether you wish to use.

Why are JavaScript function objects allowed to differ from the string to value map format?

In JavaScript, objects have properties and values:
var o = {
prop1: "value",
prop2: 3
}
My understanding is all JavaScript objects must look like this (i.e. have properties and values only). But, functions (I'm not talking about methods) are objects too:
function f() {
console.log("Hello");
}
Why is it possible for my function object to differ from the {property:value} style of object that is o?
Update: To try to explain my question further:
Objects are described in almost every book I've ever read as string to value maps. For example, they map a property name to a property value:
{
property1: value,
property2: value
}
Functions are objects, however they do not look at all like string to value maps:
function my_f() {
// code here.
}
Why are function objects allowed to differ from the string to value map format?
Well, In javascript, functions can be treated as Classes in other Object Oriented Languages.
This means that you can instantiate a new object from the function using the new keyword
Example:
function myFunc(){
//Some code goes here
}
var myObj = new myFunc();
You can attach properties to this Class using this keyword
Example:
function myFunc(){
//this is a public property for any myFunc object
this.name="My_Name";
//this is a private property
var age = 22;
}
var myObj = new myFunc();
console.log(myObj.name); //Will output "My_Name"
console.log(myObj.age); //undefined
Everything is object in JS.
var o = {
prop1: "value",
prop2: 3
}
is just a shortcut for object creation instead of using the Object constructor(and is fast too). Same goes with functions.
Consider
var adder = new Function('a', 'b', 'return a + b'); console.log(adder.prototype)
Its an object with the constructor and other properties with corresponding values.
I think what you're asking about is, at its heart, the difference between a function declaration and a function expression. These are just different ways that Javascript allows variables/properties of type Function to be created.
You can, of course, define a function as the inline value for a property, as you would any object literal:
var Foo = {
bar: function(){
console.log("bar");
}
};
You can also define as a property this way:
var Foo = {};
Foo.bar = function(){
console.log("bar");
};
Or you can assign the result of the function expression directly to a variable:
var bar = function(){
console.log("bar");
};
These examples should demonstrate that functions are like any other variable/property in Javascript. They have a type, just like a String or a Number. A string is also an object, but you don't need curly braces to create a string:
var foo = "foo";
A function declaration, as you're describing in your question is a slightly different way of defining a function:
function bar(){
console.log("bar");
}
I believe that they included this additional function syntax in the language for one main reason: hoisting.
Including this alternate syntax that hoists function declarations "up above" other expressions allows coders to be a little bit more loose with the order in which they define their variables and functions.
There are arguments to be made both in favor of function declarations and function expressions, but I tend to use the function expression syntax, as I like that it is more consistent and less surprising for new team members.
UPDATE:
Perhaps you are overthinking this idea that "Objects are described in almost every book I've ever read as string to value maps. For example, they map a property name to a property value:"
A string is an Object, a function is also still an Object. Try this:
var foo = "foo";
foo.bar = "bar";
console.log(foo, foo.bar);
Or this:
var foo = function(){
console.log("foo");
};
foo.bar = function(){
console.log("bar");
};
console.log(foo(), foo.bar());
The syntax for creating object literals in Javascript can involve defining the key/value pairs, yes. But there are lots of ways to create variables and properties of various types, many of which ultimately inherit from the Object prototype, including the Function type.
The different syntaxes all result in the same types of Objects being created. The only thing that matters is the order of declaration/execution, as defined by the hoisting rules.
After 5 minutes of looking into your question with a wierd look i think i finally understood what you want to know.
You, in-fact, ask why is the consistency of the Object in javascript is different when using function or key:value kind of option.
Well, javascript is a
dynamic, weakly typed, prototype-based language with first-class functions
If I can quote wikipedia here.
This means that everything in this so-called language is Object base, if you know c# from example, its like everything is object type and there aren't any other primitive-type objects.
With that being said, object is mostly like a memory entry and not a real value of things, unlike int, string, char etc.
Therefore, functions are actually stored in memory as same as objects do.
if you look on other elite-type languages you can see that object there can store perhaps everything, even an entire solution, it doesn't have any bounds.
In unrelated matter, I would like to recommend you to read about "boxing" and "unboxing" of elements to understand the idea behind objectifying stuff.
Why are function objects allowed to differ from the string to value map format?
Exactly because its just a memory reference and the "syntax" isn't really important, if you try to execute some operation that belongs to a method and not for a normal type object like {key: "value"} the execute will first approach the object in the memory and try to operate () on it, it will throw an error unless the () operation is defined for this object.
hope I made myself clear enough
EDIT
ok, ill explain more, as you wish.
basically there are 2 ways in which data storing is occurring.
Heap memory (not the data structure), if to quote Wikipedia again is
very simple explanation is that the heap is the portion of memory where dynamically allocated memory resides
In easy words, it means you save something by its value and you use it in different ways as value.
so you ask yourself, what does it mean "not by value"
Memory reference (stack), that means that every non-primitive object you create is assigned with its own memory address, in fact every time you create an object you're allocating space in your memory, just to be clear, all javascript's data storing is done by this way, unlike any elite-type language such as java,c,c++,c# and so on..
now, why am i saying this?
because when i create an object, a reference, i can create a reference to whatever i want to, it can be an object that describes Human, function, document or even a file. I will be very careful with what im about to say, javascript doesnt let you distinct between objects, an object is an object, of course each has its own properties, but that is only important when you try to execute things with that object.
if you are familiar with c# (always bringing this up because its commonly wide-spread language) you'll notice that you have both objects that you create, methods, threads,task,solutions and possibly every type of data, and they are all objects before they are themselves.
as to conclude:
object in javascript is a matter of principle and not data type.
encourage you strongly to read an article, heap vs stack
After doing a little more research of my own, I found out function objects are a special type of object. Aside from being a regular object which has any number of properties and values, function objects are also callable blocks of code. This extra "capability" (I couldn't think of a better term) is something that is added by JavaScript itself.

What is difference between function FunctionName(){} and object.FunctionName = function(){}

Today while working my mind was stack at some point in javascript.
I want to know that what is basic difference between
function FunctionName(){
//Code goes here;
}
And
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
//Code goes here;
}
Both are working same. Then what is difference between then. Is there any advantage to use function with object name?
I have read Question. But it uses variable and assign function specific variable. I want to create object and assign multiple function in single object.
The first one defines a global function name. If you load two libraries, and they both try to define FunctionName, they'll conflict with each other. You'll only get the one that was defined last.
The second one just has a single global variable, MyFuncCollection. All the functions are defined as properties within that variable. So if you have two collections that try to define the same function name, one will be FuncCollection1.FunctionName, the other will be FuncCollection2.FunctionName, and there won't be any conflict.
The only conflict would be if two collections both tried to use the same name for the collection itself, which is less likely. But this isn't totally unheard of: there are a few libraries that try to use $ as their main identifier. jQuery is the most prominent, and it provides jQuery.noConflict() to remove its $ binding and revert to the previous binding.
The short answer is, the method in object context uses the Parent Objects Context, while the "global" function has its own object context.
The long answer involves the general object-oriented approach of JavaScript, though everything in JavaScript is an object you may also create arrays with this Method.
I can't really tell you why, but in my experience the best function definition is neither of the top mentioned, but:
var myFunction = function(){};
It is possible to assign function to variables, and you may even write a definition like this:
MyObject.myMethod = function(){};
For further reading there are various online Textbooks which can give you more and deeper Information about this topic.
One main advantage I always find is cleaner code with less chance of overwriting functions. However it is much more than that.
Your scope changes completely inside the object. Consider the following code ::
Function:
function FunctionName(){
return this;
}
FunctionName()
Returns:
Window {top: Window, location: Location, document: document, window: Window, external: Object…}
Object:
var MyFuncCollection = new Object();
MyFuncCollection.FunctionName = function(){
return this;
}
MyFuncCollection.FunctionName()
Returns:
Object {}
This leads to some nice ability to daisy chain functions, amongst other things.
The first:
function functionName (){
//Code goes here;
}
Is a function declaration. It defines a function object in the context it's written in.
Notice: this doesn't have to be the global context and it doesn't say anything about the value of this inside it when it's invoked. More about scopes in JavaScript.
Second note: in most style guides functions are declared with a capitalized name only if it's a constructor.
The second:
var myFuncCollection = {};
myFuncCollection.functionName = function () {
//Code goes here;
};
notice: don't use the new Object() syntax, it's considered bad practice to use new with anything other then function constructors. Use the literal form instead (as above).
Is a simple assignment of a function expression to a property of an Object.
Again the same notice should be stated: this says nothing about the value of this when it's invoked.
this in JavaScript is given a value when the function object is invoked, see here for details.
Of course, placing a function on an Object help avoiding naming collisions with other variables/function declarations in the same context, but this could be a local context of a function, and not necessarily the global context.
Other then these differences, from the language point of view, there's no difference whatsoever about using a bunch of function declarations or an Object with bunch of methods on it.
From a design point of view, putting methods on an Object allows you to group and/or encapsulate logic to a specific object that should contain it. This is the part of the meaning of the Object Oriented Programming paradigm.
It's also good to do that when you wish to export or simply pass all these functions to another separate module.
And that's about it (:

Relationship of Function object and Javascript object

Recently I read a tutorial which says if define the function like below.
function Animal() { }
On the surface, this code seems to create a function called Animal.
But with JavaScript, the full truth is slightly more complicated. What
actually happens when this code executes is that two objects are
created. The first object, called Animal, is the constructor function
itself. The second object, called Animal.prototype, has a property
called Animal.prototype.constructor, which points to Animal. Animal
has a property which points back to its prototype, Animal.prototype.
But I have little confuse about it .What about the Function object ?What is the use for the Animal object?
And If I write code like below .
var test= new Function();
and I inspected the variable test in the Developer tool of the Chrome.
I found test is nothing to do with the Function. Can someone tell me why ? thanks.
Updated
The diagram below is the objects relationship when the code is executed, please review it.
If my understanding is wrong. please correct me. thanks.
That blog post goes into a lot of detail that's interesting but unnecessarily confusing for most people most of the time.
First, let's talk about functions; forget about prototypes for a minute. When you create a function:
function Whatever() {
// ...
}
you've created an object. That is, all functions are objects, and they're constructed via the Function built-in constructor. The symbol "Whatever" in this example will have as its value a reference to that object.
Given a reference to a function, it's possible to call it:
Whatever(); // call the function
It's possible to take that value (the reference to the function object) and assign it to another variable, or pass it as a parameter to another function, or to use it just like any other value in JavaScript.
var another = Whatever;
another(); // also calls the "Whatever" function
Constructing a function via the Function constructor explicitly is something that's rarely done, but it gives you a function that's otherwise unremarkable. (In the OP, the constructed function doesn't do anything because no code was passed to the Function constructor.)
Now, things get interesting when a function is invoked as part of a new expression.
var test = new Whatever();
By using new, a new object is instantiated and associated with the "Whatever" function. The "Whatever" function is the constructor for that new object.
Every function object, whether it's ever used as a constructor or not, has an associated "prototype" object. When a function is used as a constructor, then objects it constructs (that is, objects made in new expressions that invoke the function) are implicitly associated with that prototype object.
The prototype object becomes interesting when an object property reference expression is evaluated. Object property references look like this:
obj.name
obj[ nameExpression ]
In such an expression, the property name (either the identifier used in the . expression or the value of the expression inside [ ]) is checked against the set of properties on the object directly. If the name is not the same as one of the object's properties, then the runtime consults the prototype object associated with the constructor function used to make the object.
For most code that most people write, that relationship and some of its direct implications are the only things to worry about. You don't have to fool around with the (non-standard, at this time) "proto" property of objects unless you're putting together some sort of library or framework.
Finally, it might be instructive to look at the Object.create() function and in particular the "polyfill" shown in that documentation.

OO Javascript callbacks: Am I doing it right?

Background: I am building a webapp that makes use of JQuery and the Facebook Javascript API. Since some users don't like Facebook, I have also built a thunking layer that emulates the necessary identity APIs for users who prefer not to use Facebook. To keep things clean and avoid code duplication, I have organized my Javascript code into a few classes.
Both Facebook and JQuery APIs make extensive use of callbacks. Since all of my functions are bound into objects, I found that I am using the following pattern frequently:
var obj_ref = this;
some_jquery_function_that_takes_a_callback(/* various args */,
function() { obj_ref.my_callback_method(); });
For readability, the obj in obj_ref is actually the name of the class.
Is there some nifty Javascript magic that is simpler or clearer, or is this as good as it gets?
Update: Some good commentary so far in the answers. I should have added that my callback methods generally needs to refer to variables or functions bound to the class. If I don't need that, then the anonymous function wrapper is unnecessary.
Update2: I've selected a best answer, but you should carefully read all of the answers. Each provides some useful insight into possible solutions.
If you need your this to be your obj_ref and you can assume an update to date JavaScript (which sadly you probably can't), you could use bind to do away with the wrappers:
Creates a new function that, when called, itself calls this function in the context of the provided this value, with a given sequence of arguments preceding any provided when the new function was called.
Then you could bind your methods to your objects and this:
some_jquery_function_that_takes_a_callback(/* various args */,
function() { obj_ref.my_callback_method(); });
would be the same as:
// In some initialization pass...
obj_ref.my_callback_method = obj_ref.my_callback_method.bind(obj_ref);
// And later...
some_jquery_function_that_takes_a_callback(/* various args */,
obj_ref.my_callback_method);
Then this would be obj_ref when my_callback_method is called.
Alternatively, you could pull in Underscore.js and use its bind or bindAll. You could always grab just bind or bindAll out of Underscore.js if you didn't want the whole thing.
Or, since you have jQuery in play already, you could use $.proxy in place of the standard bind:
Takes a function and returns a new one that will always have a particular context.
So you could do it like this:
// In some initialization pass...
obj_ref.my_callback_method = $.proxy(obj_ref.my_callback_method.bind, obj_ref);
// And later...
some_jquery_function_that_takes_a_callback(/* various args */,
obj_ref.my_callback_method);
Thanks to dsfq for reminding me about jQuery's version of bind.
Better to use binding to the your object to preserve invocation context:
var objRef = this;
// #1. In this case you will have wrong context inside myCallbackMethod
// often it's not what you want. e.g. you won't be able to call another objRef methods
someJqueryFunction(a, b, objRef.myCallbackMethod);
// #2. Proper way - using proxy (bind) function
someJqueryFunction(a, b, $.proxy(objRef.myCallbackMethod, objRef));
I have the same problem with callbacks. Here's how I've dealt with it.
Just like dfsq said, $.proxy does the job for you. You don't need any extra library like underscore.
Underscore js has it's own bind function which is like the $.proxy.
Apply and call (the javascript methods that can be called on functions) work great.
Let's say I have a object :
var Dog = {
name : "Wolfy",
bark : function(){
console.debug(this.name," barks!");
}
}
var AnotherDog = {
name : "Fang"
}
Dog.bark.call(AnotherDog); //--> Fang barks!
Dog.bark(); //--> Wolfy barks!
When you write your "classes", you could use this pattern to handle the invocation of callbacks.
In case you're not sure what proxy or bind do, they do something similar to this:
var Dog = {
name : "Wolfy",
bark : function(){
console.debug(this.name," barks!");
}
}
Dog.bark = funciton(){
var scope = Dog;
return Dog.bark.apply(scope,arguments);
}
Rewrites the bark function by wrapping it in a new functions which returns the result of the original function, but forces a specific scope to be used.
I usually only wrap the callback in a function when I have to pass in extra parameters:
var x = 42;
jQuery_something({}, function(y, z) { obj_ref.callback(x, y, z) });
And that is because you don't control the arguments passed into the callback yourself. But this is only if you need a reference to some var in the scope. And in some cases this means you will have to create a closure to capture the var, e.g. in a loop.
But if that's not the case, then I just pass in a reference to the function directly:
jQuery_something({}, obj_ref.callback);
Even this should work fine, since the callback reference is in scope in this particular example (so no need to copy it to obj_ref first:
jQuery_something({}, this.callback);
Obviously, the last example is about as simple and clean as it gets: "the callback argument for the jQuery method is this object's method named 'callback'"
Yes, this is quite correct. You can have a helper function which implements the pattern though to save some code.

Categories