javascript - help me understand this structure (lexical scoping) - javascript

Below is simplification of some code I am trying to understand.
What are we trying to do in this javascript fragment? It seems we are creating object(?) called myCompany if not already created, then adding child object myProject to myCompany.
Then creating a local variable withinmyCompany.myProject and another local to function myCompany.myProject.myfunction. The () at the end make it execute immediately. And we are doing this to keep localVariable_1 out of global space?
var myCompany= myCompany || {};
if (!myCompany.myProject) {
myCompany.myProject = {};
}
myCompany.myProject = function () {
var localVariable_1;
function myFunction(){
var anotherlocalVariable;
// .. do some stuff
}
}();

The first line checks if the object exists, if not use shorthand definition {} to create an Object. || compares. If argument one is null set argument two.
The if on the next line checks if the property myProject isn't set on the object. ! is the operator. If myCompany.myProject returns undefined this if clause returns true. When true create object as property myProject.
Third part: myProject gets replaced by a function object. This function is defined between { and }, but is immediately called upon by the () behind the function declaration.
localvariable_1 will never be in the global scope since it has the var statement. Binding it to the scope of myCompany.myProject function. Maybe this function is directly called to set up some initial values, but wrap them in a function that could be reused to change the values at another moment.

One piece at a time...
var myCompany= myCompany || {};
if myCompany exists you set it to it, otherwise you create an empty object and set myCompany to an empty object.
NOTE: if myCompany already exists you have no indicator of what it is
if (!myCompany.myProject) {
myCompany.myProject = {};
}
Now that you know myCompany is an object you verify it has a project property on it. if not you set myProject to an empty object.
NOTE: you have tested nothing about myProject so again there is no indicator of what it is
myCompany.myProject = function () {
var localVariable_1;
function myFunction(){
var anotherlocalVariable;
// .. do some stuff
}
}();
Here you are assigning myCompany.myProject. Notice at the bottom the () before the ; That makes this function get executed immediately. Inside of the function you are creating another function that currently isn't doing anything. Where you aren't returning from the function I think it will set myProject to undefined.
You may already know what an immediate function is but if not it is basically a function that is called right away. It is also standard to wrap it in a () so that it is easier to read for example
var someFunction = (function () {
/*whatever*/
} ());
You said this was simplified from the original so I am guessing you removed an important part of the code that actually does things but the confusion is probably due to the JavaScript's way of scoping. It uses what is called Lexical scoping. You can think of it as scoping by functions.
Another thing that may be tripping you up is how JavaScript uses truthy evaluation for logical comparisons.
The last thing to mention that might be confusing the way you read the code is javascript's hoisting.
Hopefully that helps or at least points you to a few things you can look into to figure out the parts you don't exactly understand.

Sorry I just hate writing in comments lol.
If you are trying to help prevent your global scope from getting polluted then you might want to use objects and a something similar to what you are doing. Depending on how crazy you want to get you could look into Prototypical Inheritance.
A common pattern is to do something like this
var company = (function() {
var name;
var getName = function() {
return name;
};
var setName = function(n) {
name = n;
};
return {
getName : getName,
setName : setName
}
}())
Now you can do company.setName("yoda") or whatever.
This will give you a basic getter and setter where no one can change the companies name without going through your getter and setter and it also doesn't pollute the global scope. You can have whatever you want on company this way and you also encapsulate the data within the object.
Notice how var company = a function that is called immediately which returns an object that has whatever you want to encapsulate on it.
Is that what you are talking about?

Related

private function return the last instance [duplicate]

Stylistically, I prefer this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
};
To this structure:
var Filter = function( category, value ){
this.category = category;
this.value = value;
};// var Filter = function(){...}
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
Functionally, are there any drawbacks to structuring my code this way? Will adding a prototypical method to a prototype object inside the constructor function's body (i.e. before the constructor function's expression statement closes) cause unexpected scoping issues?
I've used the first structure before with success, but I want to make sure I'm not setting myself for a debugging headache, or causing a fellow developer grief and aggravation due to bad coding practices.
Functionally, are there any drawbacks to structuring my code this way?
Will adding a prototypical method to a prototype object inside the
constructor function's body (i.e. before the constructor function's
expression statement closes) cause unexpected scoping issues?
Yes, there are drawbacks and unexpected scoping issues.
Assigning the prototype over and over to a locally defined function, both repeats that assignment and creates a new function object each time. The earlier assignments will be garbage collected since they are no longer referenced, but it's unnecessary work in both runtime execution of the constructor and in terms of garbage collection compared to the second code block.
There are unexpected scoping issues in some circumstances. See the Counter example at the end of my answer for an explicit example. If you refer to a local variable of the constructor from the prototype method, then your first example creates a potentially nasty bug in your code.
There are some other (more minor) differences. Your first scheme prohibits the use of the prototype outside the constructor as in:
Filter.prototype.checkProduct.apply(someFilterLikeObject, ...)
And, of course, if someone used:
Object.create(Filter.prototype)
without running the Filter constructor, that would also create a different result which is probably not as likely since it's reasonable to expect that something that uses the Filter prototype should run the Filter constructor in order to achieve expected results.
From a run-time performance point of view (performance of calling methods on the object), you would be better off with this:
var Filter = function( category, value ){
this.category = category;
this.value = value;
// product is a JSON object
this.checkProduct = function( product ){
// run some checks
return is_match;
}
};
There are some Javascript "experts" who claim that the memory savings of using the prototype is no longer needed (I watched a video lecture about that a few days ago) so it's time to start using the better performance of methods directly on the object rather than the prototype. I don't know if I'm ready to advocate that myself yet, but it was an interesting point to think about.
The biggest disadvantage of your first method I can think of is that it's really, really easy to make a nasty programming mistake. If you happen to think you can take advantage of the fact that the prototype method can now see local variables of the constructor, you will quickly shoot yourself in the foot as soon as you have more than one instance of your object. Imagine this circumstance:
var Counter = function(initialValue){
var value = initialValue;
// product is a JSON object
Counter.prototype.get = function() {
return value++;
}
};
var c1 = new Counter(0);
var c2 = new Counter(10);
console.log(c1.get()); // outputs 10, should output 0
Demonstration of the problem: http://jsfiddle.net/jfriend00/c7natr3d/
This is because, while it looks like the get method forms a closure and has access to the instance variables that are local variables of the constructor, it doesn't work that way in practice. Because all instances share the same prototype object, each new instance of the Counter object creates a new instance of the get function (which has access to the constructor local variables of the just created instance) and assigns it to the prototype, so now all instances have a get method that accesses the local variables of the constructor of the last instance created. It's a programming disaster as this is likely never what was intended and could easily be a head scratcher to figure out what went wrong and why.
While the other answers have focused on the things that are wrong with assigning to the prototype from inside the constructor, I'll focus on your first statement:
Stylistically, I prefer this structure
Probably you like the clean encapsulation that this notation offers - everything that belongs to the class is properly "scoped" to it by the {} block. (of course, the fallacy is that it is scoped to each run of the constructor function).
I suggest you take at the (revealing) module patterns that JavaScript offers. You get a much more explicit structure, standalone constructor declaration, class-scoped private variables, and everything properly encapsulated in a block:
var Filter = (function() {
function Filter(category, value) { // the constructor
this.category = category;
this.value = value;
}
// product is a JSON object
Filter.prototype.checkProduct = function(product) {
// run some checks
return is_match;
};
return Filter;
}());
The first example code kind of misses the purpose of the prototype. You will be recreating checkProduct method for each instance. While it will be defined only on the prototype, and will not consume memory for each instance, it will still take time.
If you wish to encapsulate the class you can check for the method's existence before stating the checkProduct method:
if(!Filter.prototype.checkProduct) {
Filter.prototype.checkProduct = function( product ){
// run some checks
return is_match;
}
}
There is one more thing you should consider. That anonymous function's closure now has access to all variables inside the constructor, so it might be tempting to access them, but that will lead you down a rabbit hole, as that function will only be privy to a single instance's closure. In your example it will be the last instance, and in my example it will be the first.
Biggest disadvantage of your code is closing possibility to override your methods.
If I write:
Filter.prototype.checkProduct = function( product ){
// run some checks
return different_result;
}
var a = new Filter(p1,p2);
a.checkProduct(product);
The result will be different than expected as original function will be called, not my.
In first example Filter prototype is not filled with functions until Filter is invoked at least once. What if somebody tries to inherit Filter prototypically? Using either nodejs'
function ExtendedFilter() {};
util.inherit(ExtendedFilter, Filter);
or Object.create:
function ExtendedFilter() {};
ExtendedFilter.prototype = Object.create(Filter.prototype);
always ends up with empty prototype in prototype chain if forgot or didn't know to invoke Filter first.
Just FYI, you cannot do this safely either:
function Constr(){
const privateVar = 'this var is private';
this.__proto__.getPrivateVar = function(){
return privateVar;
};
}
the reason is because Constr.prototype === this.__proto__, so you will have the same misbehavior.

Hardcore javascript module scope

The problem : I want to iterate over my list of functions, and modify them in place, using code like:
for(var funcProperty in scope) {
scope['_'+funcProperty] = scope[funcProperty];
scope[funcProperty] = wrapFunctionInTryCatchBlock(scope['_'+funcProperty]);
}
I want to do this without explicitly having to go through all my functions, and add them to some object, thereby creating the required scope. I don't want to do that because then all the functions, which call each other, will have to have their names modified and lengthened to become:
funcName becomes scopeObject.funcName : annoying.
I could do this quite easily if my functions were in the global object, i.e, Window, however I don't want to pollute the global namespace, so I have put them in a module, like so:
var MyModule = (function() {
function privateFunc1(...) {...}
function privateFunc2(...) {...}
var public_api = {
coolName : privateFunc1
};
return public_api;
}());
However, I can see and find no way to access the scope object that exists in the immediately executed function call the return value of which is assigned to MyModule.
I tried doing this, from within MyModule:
console.log(this)
To see if we did have access to the scope, somehow, yet, of course, it turned out that this referred to Window.
My question is really: What is the scope object that the methods in MyModule private scope are assigned to, since it is not the global object, and it does exist, since all the functions have implicit access to it. Is there any way I as a JavaScript programmer can explicitly access the scope object and enumerate its properties or is that FORBIDDEN?
I'm not going to rush to accept this as the answer, but I have found one possible solution that I am happy with.
Definition of "happy with" in this case is : minimal extra work, almost no changes to existing code.
The solution
We modify the module code like so:
// $ = wrapFunctionInTryCatchBlock
function $(fun) {
return function() {
try {
return fun.apply(this,arguments);
} catch(err) {
console.log("Error",err,err.stack);
}
};
}
var MyModule = (function() {
var privateFun1 = $(privateFun1(...){...});
var privateFun2 = $(privateFun2(...){...});
var public_api = {
coolName : privateFun1
};
return public_api;
}());
Why this works
We get the desired code modification (function wrapping), essentially in place since the variables assigned to function expressions have exactly the same scope as the original named functions themselves.
A VIM regex to help
I also created a VIM regex to help with this, at least the assignment line anyway:
s/function \(\w\+\)\(.\+\)$/var \1 = $(function \1\2/g

Javascript closure & "that" instead of "this" in a specific example

I know this subject had been dealt a lot here, but I saw this specific example on the Pluralsight JS design pattern course, and I'll be glad for your help understanding the closure there.
This is the example:
var Calc = function(start) {
var that = this;
this.add = function(x) {
start = start + x;
return that;
};
this.multiply = function(x) {
start = start * x;
return that;
};
this.equals = function(callback) {
callback(start);
return that;
};
}
new Calc(0)
.add(1)
.add(2)
.multiply(3)
.equals(function(result){
console.log(result); // returns 9
});
Here's the JSFiddle link: http://jsfiddle.net/3yJ8Y/5/
I'll be VERY glad for:
Understanding the "that" use. Why do we need it in this specific
example? it does the same with "this". Can you pls give examples and explain when do we need to do "var that = this"?
Understanding this way of creating functions from an object. why do we have to use "this" and then .functionName? like this.add = ...
A detailed and extensive explanation for this very specific closure example.
Thank you so much!
start becomes a global variable of the Calc object
Each method of the Calc object (add, multiple, equals) references that same global variable
new Calc(0) // <- sets start to 0
.add(1) // calls add() <- sets start to 1
.add(2) // calls add() <- sets start to 3
.multiply(3) // calls multiple() <- sets start to 9
.equals(function(result){
console.log(result); // returns 9
});
Thanks to #elclanrs for reminding me of things I had internalized and forgotten...
That
The important thing here is that that... is unnecessary.
I'll quote an article that #elclanrs linked in his comment on the above post:
Scope In Javascript
JavaScript establishes an execution context for the function call, setting this to the object referenced by whatever came before the last ”.”
Because each method is called with the outer Calc before it's dot, the this value inside that method is assigned as the outer object.
The outer object, in turn, is its own brand new, self-contained scope because it was created with the new keyword:
When new[Calc]() is executed, a completely new object is created transparently in the background. [Calc] is called, and its this keyword is set to reference that new object.
(Scope in Javascript, again, with my edits in brackets).
Now you might be wondering, "How is this:
.add(1)
.add(2)
.multiply(3)
... keeping the right scope? You said that whatever is before the . is passed in as the this variable in this situation!?"
Absolutely true, and in this situation, each method is returning this, which allows method chaining. (They're actually returning that, but we already determined that was an unnecessary variable in this context).
Why use that
First of all, let me say I prefer var self = this over var that = this but there are arguments either way.
Let's arbitrarily modify the object to have a method that looks like this:
this.getInternalThis = function(){
var internalThis = function(){
console.log( this );
}
}
First of all, let's get this out of the way: this example is stupid, but you'll see things like this - a function defined in other scopes - all the time.
Here are the important things to notice:
It's called by name, and nothing more (no prefixed . notation, for example)
... that's it!
When a function is called this way, the engine has to figure out something to assign this as in the scope of the function. It defaults to window.
If you were to run this code, you would get Window in the console.
Now, what if we wanted this inside that internal function call to be the calling value of this?
This situation is where you need a that variable. We can modify the function to look like:
this.getInternalThis = function(){
var that = this,
internalThis = function(){
console.log( that );
};
}
Now when you run this method, you get the value of the calling object in the console.
In my case it was Object { add=function(), multiply=function(), equals=function(), getInternalThis=function()}.
Sometimes, that's what you need or expect, so that's why you would use a var that = this declaration.
Using this. to define a method
As I mentioned earlier:
Because each method is called with the outer Calc before it's dot, the this value inside that method is assigned as the outer object.
Remember that this in the scope of Calc() is a reference to the new Calc object, so each method is being given the Calc object as the value of this (remember, it's before the .!) when they enter their new scope from that context.
Hopefully this gives you a little info on how JavaScript scopes and the assignment of this works.

Javascript Function Declaration Options

I've seen experts using below to declare a function:
(function () {
function f(n) {
// Format integers to have at least two digits.
return n < 10 ? '0' + n : n;
}
//etc
}());
e.g.
https://github.com/douglascrockford/JSON-js/blob/master/json.js
Could someone help me understand when should we use above pattern and how do we make use of it?
Thanks.
Well, since ECMA6 hasn't arrived yet, functions are about the best way to create scopes in JS. If you wrap a variable declaration of sorts in an IIFE (Immediately Invoked Function Expression), that variable will not be created globally. Same goes for function declarations.
If you're given the seemingly daunting task of clearing a script of all global variables, all you need to do is wrap the entire script in a simple (function(){/*script here*/}());, and no globals are created, lest they are implied globals, but that's just a lazy fix. This pattern is sooo much more powerful.
I have explained the use of IIFE in more detail both here, here and here
The basic JS function call live-cycle sort of works like this:
f();//call function
||
====> inside function, some vars are created, along with the arguments object
These reside in an internal scope object
==> function returns, scope object (all vars and args) are GC'ed
Like all objects in JS, an object is flagged for GC (Garbage Collection) as soon as that object is not referenced anymore. But consider the following:
var foo = (function()
{
var localFoo = {bar:undefined};
return function(get, set)
{
if (set === undefined)
{
return localFoo[get];
}
return (localFoo[get] = set);
}
}());
When the IIFE returns, foo is assigned its return value, which is another function. Now localFoo was declared in the scope of the IIFE, and there is no way to get to that object directly. At first glance you might expect localFoo to be GC'ed.
But hold on, the function that is being returned (and assigned to foo still references that object, so it can't be gc'ed. In other words: the scope object outlives the function call, and a closure is created.
The localFoo object, then, will not be GC'ed until the variable foo either goes out of scope or is reassigned another value and all references to the returned function are lost.
Take a look at one of the linked answers (the one with the diagrams), In that answer there's a link to an article, from where I stole the images I used. That should clear things up for you, if this hasn't already.
An IIFE can return nothing, but expose its scope regardless:
var foo = {};
(function(obj)
{
//obj references foo here
var localFoo = {};
obj.property = 'I am set in a different scope';
obj.getLocal = function()
{
return localFoo;
};
}(foo));
This IIFE returns nothing (implied undefined), yet console.log(foo.getLocal()) will log the empty object literal. foo itself will also be assigned property. But wait, I can do you one better. Assume foo has been passed through the code above once over:
var bar = foo.getLocal();
bar.newProperty = 'I was added using the bar reference';
bar.getLocal = function()
{
return this;
};
console.log(foo.getLocal().newProperty === bar.newProperty);
console.log(bar ==== foo.getLocal());
console.log(bar.getLocal() === foo.getLocal().getLocal());
//and so on
What will this log? Indeed, it'll log true time and time again. Objects are never copied in JS, their references are copied, but the object is always the same. Change it once in some scope, and those changes will be shared across all references (logically).
This is just to show you that closures can be difficult to get your head round at first, but this also shows how powerful they can be: you can pass an object through various IIFE's, each time setting a new method that has access to its own, unique scope that other methdods can't get to.
Note
Closers aren't all that easy for the JS engines to Garbage Collect, but lately, that's not that big of an issue anymore.
Also take your time to google these terms:
the module pattern in JavaScript Some reasons WHY we use it
closures in JavaScript Second hit
JavaScript function scope First hit
JavaScript function context The dreaded this reference
IIFE's can be named functions, too, but then the only place where you can reference that function is inside that function's scope:
(function init (obj)
{
//obj references foo here
var localFoo = {};
obj.property = 'I am set in a different scope';
obj.getLocal = function()
{
return localFoo;
};
if (!this.wrap)
{//only assign wrap if wrap/init wasn't called from a wrapped object (IE foo)
obj.wrap = init;
}
}(foo));
var fooLocal = foo.getLocal();
//assign all but factory methods to fooLocal:
foo.wrap(fooLocal);
console.log(fooLocal.getLocal());//circular reference, though
console.log(init);//undefined, the function name is not global, because it's an expression
This is just a basic example of how you can usre closures to create wrapper objects...
Well the above pattern is called the immediate function. This function do 3 things:-
The result of this code is an expression that does all of the following in a single statement:
Creates a function instance
Executes the function
Discards the function (as there are no longer any references to it after the statement
has ended)
This is used by the JS developers for creating a variables and functions without polluting the global space as it creates it's own private scope for vars and functions.
In the above example the function f(){} is in the private scope of the immediate function, you can't invoke this function at global or window scope.
Browser-based JavaScript only has two scopes available: Global and Function. This means that any variables you create are in the global scope or confined to the scope of the function that you are currently in.
Sometimes, often during initialization, you need a bunch of variables that you only need once. Putting them in the global scope isn't appropriate bit you don't want a special function to do it.
Enter, the immediate function. This is a function that is defined and then immediately called. That's what you are seeing in Crockford's (and others') code. It can be anonymous or named, without defeating the purpose of avoiding polluting the global scope because the name of the function will be local to the function body.
It provides a scope for containing your variables without leaving a function lying around. Keeps things clean.

Javascript: Get Name of Current Object Property in Object Literal

File this one under "just curious" or "is it possible?"
Say for example I have...
home: function(options) {
this._home('home', options)
}
login: function(options) {
this._home('login', options)
}
home and login are obviously identifiers on dozens of object properties for tracking purposes. Is there a way to just return home or login without using any variables (an external function call is fine) within the object property?
UPDATE: Turns out this isn't possible. The accepted answer doesn't exactly answer the question, but it is a wonderful example of simplifying numerous calls to the same property.
If you mean that within the function that the home property references you want to be able to somehow get the string "home" from that property name without hardcoding it then no, to the best of my knowledge that isn't possible.
Just guessing at what you're trying to achieve, would something like this help at least a little bit:
function callHome(propName) {
return function(options) {
this._home(propName, options);
}
}
var someObj = {
home: callHome('home'),
login: callHome('login')
}
someObj.home({some:"option"});
At least then you don't have to repeat the same function body for each property. Demo: http://jsfiddle.net/EeEAw/
Note: I assume that the _home() function invoked but not defined in the question would be defined somewhere in the real-world code. I don't show it in my answer, though I created a dummy one in my fiddle.
Just as an aside, note that the function doesn't really "belong" to the object or to the property - there's nothing stopping you doing this sort of thing:
var obj = {
test : "test",
home : function() {
alert(this.test);
}
};
var funcRef = obj.home;
var obj2 = {
method1 : funcRef
}
obj.home = null;
funcRef();
obj2.method1();
That is, you can create multiple references to the same function, and the function will continue to exist even if the original obj.home property is set to some other value (as long as the additional references continue to exist).
Identifier resolution and object property look up use completely separate methods. You can use with to add an object to the top of the scope chain, but it is very much recommended against and may well fail completely in strict mode.
So if you have:
var obj = {test:'test'};
alert(test);
then the identifier test is resolved on the scope chain. Since it doesn't exist there, an error is thrown. However, for:
alert(obj.test);
then firstly obj is resolved and found as a reference to an object, then the identifier test is resolved as a property of the object. You can also use with:
with (obj) {
alert(test);
}
in which case obj is temporarily placed at the top of the scope chain and so test is resolved on it first.

Categories

Resources