Javascript: what does this code do?

I apologize for being advanced if this question is too broad. These are actually 4 different questions, but they are all related to the same piece of code, and I think that they all revolve around the same principle.

Today, I decided to use JS for many years to start learning how JS works, rather than treating it as C, which works in a browser. So I'm starting to delve into jQuery code to see how real JS developers use langauge. This is when I found a block of code that looks like the code below. Notice, I took this code from another posted post here. In Javascript, can you extend the DOM? . So this does not mean that the person who wrote this code even knew what he was talking about.

var myDOM = (function(){ // #1 var myDOM = function(elems){ // #2 return new MyDOMConstruct(elems); }, MyDOMConstruct = function(elems) { this.collection = elems[1] ? Array.prototype.slice.call(elems) : [elems]; return this; // #3 }; myDOM.fn = MyDOMConstruct.prototype = { forEach : function(fn) { var elems = this.collection; for (var i = 0, l = elems.length; i < l; i++) { fn( elems[i], i ); } return this; }, addStyles : function(styles) { var elems = this.collection; for (var i = 0, l = elems.length; i < l; i++) { for (var prop in styles) { elems[i].style[prop] = styles[prop]; } } return this; } }; return myDOM; // #4 })(); 

1 Why declare a function with var myDOM = (function () {}) (); instead of var myDOM = function () {};

2 Why declare another function inside the myDOM function with the same name? Why not put all the internal logic of myDOM inside the external function myDOM?

3 Why do I explicitly return "this"? That would be done automatically, right?

4 What is going on here? Does it return the internal constructor myDOM? If so, why?

Update

So much of this makes sense now. As for No. 1, I thought that myDOM is assigned a function defined after =, but it is not. It is assigned by what this function returns. It is just a function.

I still don’t understand, # 3. Yes, I understand using a function like this

 console.log(MyDomConstruct('foo')) 

'Undefined' will be displayed. But that is not how it is used. A few lines up this

 return new MyDomConstruct(elems); 

I can understand the expression returning "this" if the statement looked like this

 return MyDomConstruct(elems); 

But this is not so.

+7
javascript jquery
source share
5 answers

Why declare a function with var myDOM = (function () {}) (); instead of var myDOM = function () {};

This is called a self-invoking anonymous function or self-executing anonymous function . He does just that, he calls himself at runtime. You will also see a template:

 (function($){ }(jQuery)); 

quite a lot in the jQuery world. The same thing, at runtime, the function calls itself and ensures that the $ sign has a reference to the jQuery object inside the function body.

In your fragment, the function calls itself and returns a myDOM function reference.

Why declare another function inside the myDOM function with the same name? Why not put all the internal logic of myDOM inside the external function myDOM?

This is just an agreement. It could be called what you want, perhaps the author thought it was convenient to do. The reason for this pattern is privacy and security. myDOM returning the internal myDOM reference, a closure is created. So, after declaring something like

 var mytest = myDOM([]); 

you will not have access to MyDOMConstruct , but your internal function has access. This way you can protect your methods and variables. It is also called method pattern . It is always good to read in this context Douglas Crockford: Javascript the good parts .

Why do I explicitly return "this"? That would be done automatically, right?

No, the function will return undefined by default. Explicitly returning this , you can chain use the following methods (from the above call):

 mytest.forEach([]).addStyles([]); ... 

since each method returns a call object, in this case myDOM .

What's going on here? Does it return the internal constructor myDOM? If so, why?

Hope this should be clear at this point.

Edit

Based on your update:

 new MyDOMConstruct(); 

creates a new object that inherits from

 MyDOMConstruct.prototype 

Without a new keyword this will not be bound to a new object. Instead, it will be bound to a global object (window), and you will access global variables using this .

+9
source share

1. Why declare a function with var myDOM = (function() {})(); instead of var myDOM = function() {};

The form used is a self-fulfillment function. This means that myDOM is set to what the function returns. The second form sets myDOM to a function, but does not immediately execute the function.

 var myDOM = (function() { // <== This is a function that does something // Something })(); // The function is executed right HERE with (). 


2. Why declare another function inside the myDOM function with the same name? Why not put all the internal logic of myDOM inside the external function myDOM?

Because you are returning the internal function myDOM at the end ... so naming really makes sense, although it is confusing at first. This is often used to create private variables in JS. Since the internal function will have access to the area in which it is enclosed (a self-executing anonymous function), but the user will not.

 var myDOM = (function() { // <== This is a function that is going to return // a function / object var myDOM = function() { // <== We're going to return this ... // The outer myDom will be set to it }; // So it actually helpful to name // it the same for clarity. return myDOM; })(); // Now we can access that inner object by using the outer myDOM. // We could access the inner object using myDOM even if the inner object // was named otherTHING... It confusing to acces something // called otherTHING in the code by // writing myDOM().... so better name the inner returned function // myDOM as well. 

That way, the internal object could be called anything, and it could be executed using myDOM() , but if you call the internal function blah , but you can still execute it using myDOM() ... that doesn't very clear ... it is much better to call it one and the same.

3. Why explicitly return "this"? That would be done automatically, right?

No, if you do not write anything, Javascript will automatically return undefined . MDC Link :.

Returning this often used to save the context of a method. It used to make the chain of methods ( $(here).is().a().chain().of().methods() ) possible. So the method down the chain knows the context in which it works.

+6
source share

Another note to the self-executing anonymous function. Wrapping some JavaScript fragments in a block (function() { })(); is a way to create a private namespace. Everything that you do inside the internal function will be closed by the function, except for the return value (in this case myDOM ).

That is, you can do things like

 var counter = (function() { var i = 0; var counter = function() { alert(i++); return i; } return counter; })(); counter(); // will alert 0 counter(); // will alert 1 // ... and so on 

to keep the secret of the internal state outside the function. The second reason, as already mentioned in other posts, is that it will not pollute the global namespace of variable i . This is why it is best to use such features in developing a jQuery plugin.

+3
source share

same as this one:

 (function () { function b(a) { return new c(a) } function c(a) { this.a = a[1] ? Array.prototype.slice.call(a) : [a]; return this } bb = c.prototype = {}; return b })(); 

hope this helps ... :)

+1
source share

for example: var fn = (function () {return function () {alert (11)};}) (); when you run the code, now the function fn = function () {alert (11)}; try it!

+1
source share

All Articles