I was reading javascript Modular pattern from this url http://viralpatel.net/blogs/javascript-module-pattern/ and
http://www.codeproject.com/Articles/247241/Javascript-Module-Pattern
and some time confusion arise in my mind. so here i am putting things where i get some confusion. please help me to understand all.
Question 1
see the below code. all private variable and function declared in module with var keyword. here pub object also declared with var keyword.
it means pub is private. so when pub is private then how people can call pub related function from out side like below code
calling syntax
CalcModule.add(2,10);
CalcModule.add(5,15);
CalcModule = (function(){
var pub = {};
var mem = new Array(); //private variable
var storeInMemory = function(val) { //private function
mem.push(val);
};
pub.add = function(a, b) {
var result = a + b;
storeInMemory(result); //call to private function
return result;
};
pub.sub = function(a, b) {
var result = a - b;
storeInMemory(result); //call to private function
return result;
};
pub.retrieveFromMemory = function() {
return mem.pop();
};
return pub;
})();
CalcModule.add(2,10);
CalcModule.add(5,15);
console.log(CalcModule.retrieveFromMemory()); //outputs 20
console.log(CalcModule.retrieveFromMemory()); //outputs 12
Question 2
Separating Module across different JS files: Augmentation
file1.js
var CalcModule = (function($, pub){
//jQuery will still be available via $
var mem = new Array(); //private variable
pub.storeInMemory = function(val){
mem.push(val);
};
pub.retrieveFromMemory = function(){
return mem.pop();
};
return pub;
})(jQuery, CalcModule || {});
file2.js
var CalcModule = (function($, pub){
//jQuery will still be available via $
pub.add = function(a,b){
var result = a + b;
pub.storeInMemory(result);
return result;
};
pub.sub = function(a,b){
var result = a - b;
pub.storeInMemory(result);
return result;
};
return pub;
}(jQuery, CalcModule || {}));
see this function($, pub) syntax. why dollar sign is there and why pub need to pass there.
Question 3
what is the difference between module Augmentation and sub module ?
Question 4
Extending existing module module
var Module1 = ( function (oldModule) {
var
//assigning oldmodule in to a local variable.
parent = oldModule;
//overriding the existing privileged method.
parent.privilegedMethod = function ( ){
//do something different by overriding the old method.
};
//private method accessing privileged method of parent module.
var privateMethod2 = function ( ) {
parent.privilegedMethod();//can access privileged method of Module
parent.publicMethod1(); //can access public method of Module
}
return {
newMethod : function ( ) {
///do something for this brand new module.
///use some functionality of parent module.
/// parent.privilegedMethod( );
}
};
} )(Module);//
Module object is the existing module that I want to extend.
how anyone can understand the above code extend the module. just by this syntax (Module) ?
Question 5
if we write module in 5 separate js file then which file we need load first. what will be the order of loading those module related s file ?
Answer 1
Because at the end it's returning pub so you'll have access to all its methods
CalcModule = (function(){ return pub; }());
CalcModules === pub
Answer 2
function($, pub)
This is the declaration of the anonymous function that is called at the end of the code
Here we have the effective call passing jQuery and your module
(jQuery, CalcModule || {}));
N.B.
We are passing jQuery as first parameter and CalcModule as second only if exist otherwise an empty object (CalcModule OR {}).
The first time the function is called CalcModule doesn't exist and so you'll end up passing an empty object, the second time CalcModule exist because has been created by the previous call.
This is done to make it order agnostic.
So we can deduce
First Call
$ === jQuery
pub === {}
Second and next Calls
$ === jQuery
pub === CalcModule
You have to pass CalcModule to the function so it can be expanded.
This
(function($, pub){...}(jQuery, CalcModule || {}));
is exactly equal to this
var anonFunc = function($, pub){...};
anonfunc(jQuery, CalcModule || {});
Answer 3
Augmentation: you are adding functionality to the same module
pub.add = function(a,b){}
pub.sub = function(a,b){}
Sub-Module: you are adding a module to another module
subModule.add = function(a,b){}
subModule.sub = function(a,b){}
pub.subModule = function(a,b){ return mySubModule; }
Answer 4
You are passing Module but it's creating a brand new module that can USE the Module you have passed, this is more like a sort of Inheritance than Augmentation
Answer 5
Depends, but generally it's indifferent because you're just declaring the functionalities of your Module.
The only case where you need to respect an order is when a functionality construction depends on another functionality of the module.
Related
So the first one being something like:
myFile.js
var name = "Peter";
module.exports.sayHello = function () {
console.log('Hello ' + name);
}
And the second one
myFile.js
module.exports = function () {
var name = 'Mary';
function sayHello () {
console.log('Hello ' + name);
}
return {
sayHello : sayHello
};
}();
Essentially it's the same thing right? If not, what's the difference and what's the pros and cons of each method?
Why do we need modules?
When you have a code like this:
// module 1
var a = 1;
var x = function (){
return a;
};
// module 2
var a = 2; // duplicated variable declaration
var y = function (){
return a;
};
// main
console.log(x()); // BUG: this should read value from module 1 instead of module 2
console.log(y());
It will lead to error, since the a variable was already taken by the first module. You need to define modules somehow.
Using a prefix
By old-style procedural programming you would add a prefix to separate modules:
// module 1
var m1_a = 1;
var m1_x = function (){
return m1_a;
};
// module 2
var m2_a = 2;
var m2_y = function (){
return m2_a;
};
// main
console.log(m1_x());
console.log(m2_y());
But this makes the code less readable.
Using closures
By javascript you have closures, which make things a little bit easier:
// module 1
var x = (function (){
var a = 1;
var x = function (){
return a;
};
return x;
})();
// module 2
var y = (function (){
var a = 2;
var y = function (){
return a;
};
return y;
})();
// main
console.log(x());
console.log(y());
But still you have different modules in a single file, so that file will be really big and hard to maintain.
Using the node.js module loader
By node.js you can move the code of different modules to separate files, so it will be easy to maintain the code of different modules, since you will be able to find the relevant part of the code much faster:
m1.js
var a = 1;
var x = function (){
return a;
};
module.exports = x;
m2.js
var a = 2;
var y = function (){
return a;
};
module.exports = y;
main.js
var x = require("m1");
var y = require("m2");
console.log(x());
console.log(y());
You can do the same in the browser
The simplest node.js style browser module loader I could come up with so far, is this:
var cache = {};
function require(name){
if (name in cache)
return cache[name];
var uri = "./" + name + ".js";
var xhr = new XMLHttpRequest();
xhr.open("GET", uri, false);
xhr.send(null);
var moduleCode = xhr.responseText;
var fn = new Function("module", moduleCode);
var module = {};
fn(module);
cache[name] = module.exports;
return cache[name];
};
Ofc. it is much safer to use browserify, webpack, require.js and other more sophisticated libs, I just wanted to show you, it is not that hard to write a loader.
What did we learn from all of this?
Both node.js modules and closures are for modularization. You should not mix them, since they solve the same problem, and mixing them will lead only to confusion!
For me it's the same thing.
Maybe the first example is more common.
You can use both, according to the rest of your code.
Yes they are basically the same. You just don't need the verbosity of the second example.
In the first example you are adding a named property to the already existing module.exports object injected by node.js, in the second example you are overriding the original object - there is no difference for the consuming end.
Lets go to the basics of module mechanism in NodeJS. For every JS
file the ground reality is which happens on the top of file:
var exports = module.exports = {};
Whenever we try to fetch the import it retrieves module.exports only
If we do both in Js file
exports.key = "key1" and module.exports = {key : "VAL"}
only the module.exports is fetched during the import according to the rule.
Now coming back to your question Adding module.exports.sayHello will
add the reference to the {} which is common with exports variable too.
However if you do
module.exports = function () {} // some function
it breaks the chain and it is only assigned to module.exports and not
exports variable.
This is why if we add any key to exports variable is retrieved via
module.exports during import! Hope it clarifies!
A very good article on this https://www.sitepoint.com/understanding-module-exports-exports-node-js/
I am studying prototypes, classes and modular patterns with Alex MacCaw's Javascript Web Applications. Almost everything is clear and well-explained, however, I can't figure out how empty functions that are used for initialization work. I would be grateful if your explain nuances no matter how complex they are.
Here is the example from the book:
(function($){
var mod = {};
mod.create = function(includes){
var result = function(){
this.init.apply(this, arguments);
};
result.fn = result.prototype;
result.fn.init = function(){};
result.proxy = function(func){ return $.proxy(func, this); };
result.fn.proxy = result.proxy;
result.include = function(ob){ $.extend(this.fn, ob); };
result.extend = function(ob){ $.extend(this, ob); };
if (includes) result.include(includes)
return result;
};
exports.Controller = mod;
})(jQuery);
From the code above I understand that the Immediately Invoked Function Expression (IIFE) is used to protect the scope. Then mod.create construction function is defined that returns result object with all class methods. However, I am confused with how the following works:
this.init.apply(this, arguments);
result.fn.init = function(){};
I guess that we apply empty init function to constructor arguments to allow new objects instantiation or something like that. From the answer below it appears that init function receives undefined number of arguments, but what arguments? Those that are used during instantiation -- includes in the above code? And why this function is empty, what it does when invoked?
this.init.apply(this, arguments);
is basically just
this.init(arguments[0], arguments[1], ..., arguments[N]);
But as soon as we don't know the exact number of arguments - we just use .apply()
Usage example:
var newConstructor = exports.Controller.create();
newConstructor.include({
init: function(a, b, c) { console.log(a, b, c, 'yay!'); }
});
var newInstance = new newConstructor(1, 2, 3);
Complete demo: http://jsfiddle.net/nbq6d/1/
In a typical js class, all calls to member functions must be preceded by this. I was looking at a technique that would let me create a library of inter-dependent STATIC functions and relying on closure/scope to make things a bit easier.
Example:
var Singleton={
//main entry point
// call with fn name, args...
call:function(){
var args=[];
if (arguments.length==0) {
return;
}
// get the fn name
var fn=arguments[0];
var x;
// make args array
for (x=1;x<arguments.length;x++) {
args[args.length]=arguments[x];
}
// I want to get rid of this part
// See below for what I wish
// Here I have access to fns below due to hoisting in js
// so I put them in a map...
var fns={
test:test
// etc, more like this I do not want to type/maintain
}
// ... all so I can do this
// get my function.
var fun=fns[fn];
// instead of that, I would like to "override whitespace" and
// say something like:
// var fun=['fn_name'];
// so I can index into local scope and get a fn
//
// log error if not found
if (typeof fun=='undefined') {
loge('Singleton: function not found:'+fn);
return;
}
// ok, run the function
return fun.apply(window,args);
// the test fn accesses test2() without dot notation
function test(a){
// Note: here in test fn it can access test2()
// without using this.test2() syntax
// as you would in normal objects
var s=test2();
alert(s+' test:'+a);
};
function test2(){
return 'test2';
};
}
}
I was hoping someone more familiar with advances in javascript might have advice on how to emulate an "implied but unnecessary this", it always struck me as strange that this defaults to window, and wouldn't it be nice if this could be pointed to an anonymous object with the local scope attached.
I would love to say ['localObject'] to get something in scope.
Edit:
After seeing some of the responses, I will restate this in the form of a challenge:
What I am looking for is a syntax cheat, a way to, as #Varuna put it, "1. Access static methods without using this variable i.e. they will remain global to one another. 2. Do not want to maintain a local array for static methods and want to achieve with in the local scope itself."
Put differently, I need to have the declared functions Register themselves, but I don't want to state the function name more than once. I suppose #Varuna has a solution using eval to access the local scope.
The following approach wont work:
var o={};
o['fn']=function fn(){};
o['fn2']=function fn2(){};
...because you have to state the fn name twice, but closure is preserved.
And this:
var a=[
function fn(){}
,function fn2(){}
];
Register(a);
Will not work because, AFAIK, you lose closure, ie. fn2 cannot see fn. Which also makes the following declarative style a "this nightmare":
window.MINE={
fn:function fn(){
//this?
// want to say fn2(), not this.fn2(), nor MINE.fn2()
}
,fn2:function fn2(){
//this?
}
,deeper:{
//more
}
};
But something like this might work, if you created a weird property that does the registration on assignment:
var registar=new Registar();
registar.reg=function fn(){};
registar.reg=function fn2(){};
//then access
var fn=registar.getFn(n);
// or
var fn=registar._[n];
The above relies on js properties and having access to fn.name, which is not available in all cases AFAIK.
If I understand correctly, you want to create objects that:
have static members
... which can be accessed without using the this notation
The easiest solution (assuming I've properly understood your query), would be to simply use a closure to store your stratic fields, access them directly by name, then explicitly add them as object members.
Consider:
var myConstructor = (function(){
var foo = 'someStaticField';
var bar = function(){
alert('A static method returns ' + foo);
};
return function(){
return {
foo : foo,
bar : bar
};
};
})();
var myInstance = new myConstructor();
As per my understanding, you want to:
1. Access static methods without using this variable i.e. they will remain global to one another.
2. Do not want to maintain a local array for static methods and want to achieve with in the local scope itself.
You can check whether a method exist using eval.Check Here
Only drawback is that this will be using eval method.
Code will be:
var Singleton = {
//main entry point
// call with fn name, args...
call: function () {
var args = [];
if (arguments.length == 0) {
return;
}
// get the fn name
var fn = arguments[0];
var x;
// make args array
for (x = 1; x < arguments.length; x++) {
args[args.length] = arguments[x];
}
//check whether function exist in local scope and not in global scope
if (typeof eval(fn) !== 'undefined' && typeof window[fn] === 'undefined') {
// ok, run the function
return eval(fn).apply(window, args);
}
else{
// log error if not found
loge('Singleton: function not found:' + fn);
return;
}
// the test fn accesses test2() without dot notation
function test(a) {
// Note: here in test fn it can access test2()
// without using this.test2() syntax
// as you would in normal objects
var s = test2();
alert(s + ' test:' + a);
};
function test2() {
return 'test2';
};
}
}
How about declaring functions that can access each other in separate closure, and exporting them to main method by binding your call method to an object containing the functions? Something like previous post (modified slightly):
var Singleton = {
call: (function() {
// here 'call' is bound to object containig your test functions
// this: {test, test2}
if (0 == arguments.length) return;
// log error if not found
if ('function' != typeof this[arguments[0]]) {
console.warn('Singleton: function not found:' + arguments[0]);
return;
}
// '...index into local scope and get function
// ie. get the function by it's name
return this[arguments[0]].
apply(window, Array.prototype.slice.call(arguments, 1));
// --- or:
// you can explicitly introduce function names to current scope,
// by `eval`-ing them here (not very much preferred way in JavaScript world):
for (var fname in this)
if (this.hasOwnProperty(fname))
eval('var ' + fname + ' = ' + this[fname]);
// and you can reference them directly by using their names
var fn = eval(arguments[0]);
return fn.apply(window, Array.prototype.slice.call(arguments, 1));
}).bind(
(function() {
var _exports = {};
function test (a) {
var s = test2();
alert(s + ' test: ' + a);
}
function test2 () {
return 'test2';
}
_exports['test'] = test;
_exports['test2'] = test2;
return _exports;
})()
)};
Singleton.call('test', 'foo and stuff');
//
previous post:
You are talking about Function#bind functionality that enables 'customizing' function's context. .bind() your call method to required 'local context' like this:
var Singleton = {
//main entry point
// call with fn name, args...
call: (function() {
// here `this` (context) is object bound to `call` method
// not `global` object, which is default for 'unbound' functions
var locals = this; // {fns, shift, loge, isfunc}
var fn;
var fun;
var x;
if (arguments.length == 0)
return;
// get the fn name
fn = locals.shift(arguments);
// '...index into local scope and get a fn'
fun = locals.fns[fn];
// log error if not found
if (!locals.isfunc(fun)) {
locals.loge('Singleton: function not found:' + fn);
return;
}
// ok, run the function
return fun.apply(window, arguments);
// lock `call`'s context to provided object
// and use `this` to reference it inside `call`
}).bind({
fns: (function(_) {
// and you can '...create a library of inter-dependent STATIC functions'
// in this closure and invoke them in `call` method above
_.test = function (a) {
var s = _.test2();
alert(s + ' test: ' + a);
};
_.test2 = function() {
return 'test2';
};
return _;
})({}),
// and create couple of helper methods as well...
isfunc: (function(_getclass) {
_getclass.func = _getclass(_getclass);
return ('function' !== typeof(/foo/)) ?
function(node) {
return 'function' == typeof node;
} :
function(node) {
return _getclass.func === _getclass(node);
};
})(Function.prototype.call.bind(Object.prototype.toString)),
loge: console.warn,
shift: Function.prototype.call.bind(Array.prototype.shift)
}),
};
Singleton.call('test', 'foo and stuff');
// eof
Here's one 'in your face answer', because I really don't like what I see here.
I don't see why you need this kind of construct, you already have that as part of language core.
1. dynamic lookup
you are doing it in a rather 'unprecedented' kind of way,
hashes already do that for you, and it's lightning fast to do a hash search.
If you are eval()-ing random strings to do simple name lookup you really have to
step aside from a keybord for a while... (no offense please)
2. closures
you are saying about 'using closures' which you actualy don't use.
your call function redeclares test functions each time it gets called,
and looks the ('fresh version') functions in it's own variable scope table,
instead of lookig them up in parent scope chains (aka. closures)
outside it's lexical location
3. nfe vs. nfd
ie. named function expressions vs. named function declarations
...you cannot assign a function to a local var and have it retain closure.
It is a feature, you might not be aware of how it works (it tripped me up as well).
check this article out for clarification
4. exceptions
Singleton: function name not found... x4!
Just go ahead and call a function,
interpreter will throw for you anyway if it cannot find/execute
5. eval (aka. ^^)
Singleton.call.ctx.fun = eval(Singleton.call.ctx.fn);
eval takes any string here(#!), and gladly executes ones like:
'for(;;);', or 'while(1);'... forever.
You probably don't want to have any code running unless it was your stuff.
6. arguments handling
It is considered best practice out there to use single (Object) options parameter
to 'fine tune' any significant piece of bundled functionality,
instead of trying to figure that out by type checking provided argument list
Here's, in couple of simple lines, what I (and as I can see #Jimmy Breck-McKye) suggest you should do:
var Singleton.call = (function () {
var funcmap = {
'f_1': function () {},
// etc.
'f_N': function () {},
};
return function (options) {
// options members:
// context, (Object) context, (defaults to global if none is given)
// func, (String) function_name,
// args, (Array) arguments to pass into a function
// this line does everything your 100+ lines long snippet was trying to:
// look's up parent scope for a function, tries to run it
// passing provided data, throws if it gets stuck.
return funcmap[options.func].apply(options.context, options.args);
};
})();
//
Answering my own question here.
The core of the issue is that you cannot assign a function to a local var and have it retain closure.
Consider that when writing a function with global and window scope, this is not necessary to call another function with identical scope. Such is not the case with member functions.
Another way of saying this is that there is no space where your cursor can sit and as you declare a function it automatically gets attached to the current this.
function fn(){}// if we are in global scope, then window.fn becomes defined
// but if we are inside, say, a constructor, simple declaration will not attach
// it to this, but fn is available in scope.
Any assignment on function declaration BREAKS part of the expected closure:
var IdentifierAvailableToClosure=function Unavailable(){}
But assignment after declaration works:
function NowAvailable(){}
var SynonymAvailableToo=NowAvailable;
This is what I meant by not wanting to repeat the name twice to get the mechanism to work.
This fact made me abandon other methods and rely on eval as suggested. Here is a first draft:
// This object is an encapsulation mechanism for a group of
// inter-dependent, static-ish, functions that can call each other
// without a this pointer prefix.
// Calls take the form of:
// Singleton.call(functionName:String [,arg1]...)
// or
// Singleton.call(contextObject:Object, functionName:String [,arg1]...)
// If a context is not provided, window is used.
//
// This type of mechanism is useful when you have defined a group
// of functions in the window/global scope and they are not ready
// to be formalized into a set of classes, or you have no intention
// of doing that
//
// To illustrate the issue, consider that a function
// which is defined in window/global scope
// does not have to use the this pointer to call a function of
// identical scope -- yet in a class member function, the this pointer
// MUST be used
// Therefore, trying to package such functions requires injecting
// the this pointer into function bodies where calls to associater
// functions are made
//
// Usage is primarily for development where one has control over
// global namespace pollution and the mechanism is useful in
// refactoring prior to formalization of methods into classes
var Singleton={
// Main call point
call:function(){
// Bail with error if no args
if (arguments.length==0) {
throw('Singleton: need at least 1 arg');
}
// As all functions in the local scope library below
// have access to the local scope via closure, we want to reduce
// pollution here, so lets attach locals to this call
// function instead of declaring locals
//
// Prepare to call anon fn
Singleton.call.args=arguments;
// Make ctx have args, context object, and function name
Singleton.call.ctx=(function (){// return args,ctx,name
// out
var args=[];
//locals
var x, fn;
// collapse identifier
var a=Singleton.call.args;
// closure object avail to functions, default to window
that=window;
// first real function argument
var arg_start=1;
// first arg must be function name or object
if (typeof a[0]=='string') {// use window ctx
fn=a[0];
// if first arg is object, second is name
}else if (typeof a[0]=='object') {
// assign given context
that=a[0];
// check second arg for string, function name
if (typeof a[1]!='string') {
var err='Singleton: second argument needs to be a fn name'
+' when first arg is a context object';
throw(err)
return;
}
// ok, have a name
fn=a[1];
// args follow
arg_start=2;
}else{
// improper arg types
var err='Singleton: first argument needs to be a string or object';
throw(err)
}
// build args array for function
for (x=arg_start;x<a.length;x++) {
args[args.length]=a[x];
}
// return context
return {
args: args
,that:that
,fn:fn
};
})();
// using function library present in local scope, try to find specified function
try{
Singleton.call.ctx.fun=eval(Singleton.call.ctx.fn);
}catch (e){
console.error('Singleton: function name not found:' + Singleton.call.ctx.fn);
throw('Singleton: function name not found:' + Singleton.call.ctx.fn);
}
// it must be a function
if (typeof Singleton.call.ctx.fun !== 'function') {
console.error('Singleton: function name not found:' + Singleton.call.ctx.fn);
throw('Singleton: function name not found:' + Singleton.call.ctx.fn);
}
// library functions use that instead of this
// that is visible to them due to closure
var that=Singleton.call.ctx.that;
// Do the call!
return Singleton.call.ctx.fun.apply(that, Singleton.call.ctx.args);
//
// cool library of functions below,
// functions see each other through closure and not through this.fn
function test(s){
alert(test2()+' test:'+s);
}
function info_props(){
console.info(this_props());
}
function test2(){
return 'test2';
}
function this_props(){
var s='';
for (var i in that) {
s+=' '+i;
}
return s;
};
}
};
I'm learning node.js and interested in is there any difference between following two cases.
I.E. I have some variable myvar (like db connection or just constant string "test") that needed to be passed in many modules and submodules.
First case.
Create modules, that accept that variable as a param:
submodule.js:
var option
, submodule = {};
submodule.func = function(){
...
var something = option;
...
}
module.exports = function(opts){
option = opts;
return submodule;
}
module1.js:
var option
, submodule
, module1 = {};
module1.func = function(){
...
submodule.func();
...
var something = option;
...
}
module.exports = function(opts){
option = opts;
submodule = require('./submodule')(opts);
return module1;
}
In this case if submodule is used in several modules with same myvar value (i.e. 2 modules) submodule's module.exports function will be called 2 times. In node.js mans it said that "Modules are cached after the first time they are loaded". And I can't understand is this module cached or not.
Another case:
That myvar can be passed as parameter to module functions. So code will look like:
submodule.js:
function func(option){
...
var something = option;
...
};
exports.func = func;
module1.js:
var submodule = require('./submodule');
function func(option){
...
submodule.func(option);
...
var something = option;
...
};
exports.func = func;
So the question is:
Is there any difference between this two cases or they are same?
I'm not exactly sure what you're asking here, but if you need to pass values into your modules you should make sure to export functions that accept parameters. When they say that a module is cached, it means that your module is only initialized once. Think of your module as an object:
var a = 1;
var b = 2;
console.log("init!");
module.exports.test = function(){
console.log("this is a function!");
}
Here, a, b, and the first log will run only once. This is when the module is requested and is then cached. When you do a
var example = require("module")
If it was never created it'll initialize a, b, and do the log message. If it was already created it will just give you a reference to what you exported. Each time you call:
example.test()
It will output: this is a function!
But you will NOT get the a, b, and the first log run again.
Think of all statements not exported as private static variables of that object.
Here is another fully working example:
app.js
var s = require("./sample");
var y = require("./sample");
s.test();
y.test();
s.test();
console.log("finished");
sample.js
var a = 1;
var b = 2;
console.log("init!");
function test() {
console.log("here! " + a);
a++;
}
exports.test = test;
This all outputs:
init!
here! 1
here! 2
here! 3
finished
Does this help at all?
I mean object as in {} [object Object]. How does it do $(selector) and $.fn.init at the same time?
Can you give me a simple example please?
This isn't unique to jQuery, but an aspect of javascript. All functions are objects. E.g.:
var f = function() { alert('yo'); }
f.foo = "bar";
alert(f.foo); // alerts "bar"
f(); // alerts "yo"
Javascript is an object oriented language, so functions ARE objects, just fancy ones that you can call.
foo = function() { console.log("foo") }
foo.bar = function() { console.log("bar") }
foo() //=> prints "foo"
foo.bar() //=> prints "bar"
$ is a function.
a method of $ can return any thing.
For example:
$ = function() {
return {
foo : function() { return 'baa'; },
r1: 1,
r2 : 'string'
}
};
typeof $ <- function
typeof $() <- object
typeof $().foo <- function
typeof $().foo() <- string
typeof $().r1; <- number
typeof $().r2 <- string
jQuery or $ is an function(you know $ is an alias of jQuery).
// Define a local copy of jQuery
jQuery = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context, rootjQuery );
},
In Javascript, everything is an object even function too. Hence You can directly add properties to function.
jQuery.find = function () {
}
It is an object.
$ holds different functions.
You can test this yourself by making your own object:
var $ = {
select: function(id){return document.getElementById(id);}
}
function $(id){
return $.select(id);
}
people play around with javascript functions and it leads to interesting design patterns.. Jquery uses of many of these patterns and creates a nice wrapper around many functions.. so ultimately jquery is like a static class using which one can do really neat stuff..
like all classes it has a name and the default Name is jQuery. The $ is nothing buy an identifier that is tied into the jQuery Library and stops you from having to type “jQuery” as the identifier.
The fact that it is a $ symbol is arbitrary. At some point a decision was made to use the $ symbol but the fact of the matter is that it could have been almost any type of ECMAScript acceptable identifier.
The main reason we use $ as the identifier is that you are less likely to make simple typo mistakes when typing one character instead of a string.
Hope that makes things clear.. please correct me guys if I hv got something wrong
A simple example of say my own library would be say a calculator class
var Calculator= (function()
{
function add(a,b)
{
return a+b;
}
function subtract(a,b)
{
return a-b;
}
function multiply()
{
return a*b;
}
function log()
{
console.log("log 123")
}
return
{
add: add,
subtract: subtract,
multiply: multiply
}
}());
Now I can perform operation using the Calculator class as follows:
Calculator.multiply(Calculator.add(2,3),5);
add my local functions are private and are not exposed to be used outside. In this case my log function can't be accessed using Calculator.log it will say method not found on object.
Now coming back to your question you could do something like this:
var _=Calculator;
and now use the calc functions like
_.multiply(_.add(2,3),5);
Interestingly there is a library called underscore too..
var q=function(){};
var s = function(){
alert("base");
window.s = s;
return new q()};
q.fn = q.prototype = {};
q.fn.x = s.x = function(){alert("x");return this;};
q.fn.y = s.y = function(){alert("y");return this;};
q.fn.z = s.z = function(){alert("z");return this;};
s().y().z().x();
s.z().x().y();
var s = function(){};
s.test = function(){console.log('inside s');}
s.test();
is perfectly legal code.