Javascript module template, scope and "this"

I am trying to bow my head to creating a custom JavaScript library. I read a lot about the module template, and also read Crockford's articles on private and public members. I know what is an expression of a function called immediately, and why we are doing something like

var myLib = (function() { }()) 

However, in some cases, I still lose a bit of information about the scales and closures in general. Specific problem:

Why does the following example warn DOMWindow and not myLib object? http://jsfiddle.net/slavo/xNJtW/1/

It would be great if you could explain what this means in all the methods in this example and why.

+4
source share
4 answers

Inside any declared function (anywhere) and called as follows this will be a window object

 function anyFunc(){ alert(this); // window object } anyFunc(); var anyFunc2 = function(){ alert(this); // window object } anyFunc2(); 

If you want to create private functions and access an instance of 'myObject', you can do one of the following methods

One

 module = (function () { var privateFunc = function() { alert(this); } var myObject = { publicMethod: function() { privateFunc.apply(this); // or privateFunc.call(this); } }; return myObject; }()); module.publicMethod(); 

Two

 module = (function () { var _this; // proxy variable for instance var privateFunc = function() { alert(_this); } var myObject = { publicMethod: function() { privateFunc(); } }; _this = myObject; return myObject; }()); module.publicMethod(); 

This is the solution to your problem. I would recommend using prototype based objects.

EDIT:

You can use the first method.

In fact, here myObject is in the same scope as privateFunc , and you can use it directly inside the function

  var privateFunc = function() { alert(myObject); } 

Below is a real use case of a proxy server for this . You can also use call .

 Module = function () { var _this; // proxy variable for instance var privateFunc = function() { alert(this + "," + _this); } this.publicMethod = function() { privateFunc(); // alerts [object Window],[object Object] privateFunc.call(this); // alerts [object Object],[object Object] } _this = this; return this; }; var module = new Module(); module.publicMethod(); 
+3
source

You need to explicitly indicate that myPrivateMethod is a member of myLib:

 function MyLib () { this._myPrivateField = "private"; this._myPrivateMEthod = function () { alert(this); // Alerts MyLib function; } } var libObject = new MyLib(); 

Just remember that without using application methods, nothing in JavaScript was ever truly private!

The best way to do this is:

 function MyLib(instanceName) { this.name = instanceName; } MyLib.prototype.myPrivateFunction() { alert(this); } 

To call your method after this:

 var libObject = new MyLib(); libObject.myPrivateMethod(); // Alerts info about libObject. 
0
source

What you need to remember about the module template is that it starts once and ends. The methods that are still available for calling are closure. During the creation of the module, "this" referred to the window and was replaced by its value.

0
source

In your linked script, the keyword "this" never changes with a "new" keyword or other context change, so it still refers to the global window object.

edit: clarification

-1
source

Source: https://habr.com/ru/post/1400236/