I have been working on React/Flux and am confused over the declaration of variable outside the component as in below code.
CounterComponent.js
var count;
function getCount (){
}
var CounterComponent = React.createClass({
getInitialState: function(){
return getCount();
},
render:function(){
}
})
module.exports = CounterComponent;
As in the above code, the doubt is that the variable count and function getCount seem to be global here. Is it okay to have variables and functions declared here, outside the component or need to placed inside. This looks like global pollution.
Also, if we consider a store, have seen very examples as below, here also, the variable CHANGE_EVENT seem to be global, is that okay.
CounterStore.js
var CHANGE_EVENT = 'change';
var MainStore = assign({},EventEmitter.prototype, {
AppDispatcher.register(function(payload){
var action = payload.action;
switch(action.actionType){
}
});
});
module.exports = MainStore;
I have searched for this answer, but couldnt get the right answer. From javascript perspective it looks like its polluting global, but what about in React?
It depends on the build system you use, if you use a system like browserify or webpack, then no variables would be global.
So if you do not use a bundler library, I suggest you to wrap your source code with a anonymous function, so that you wont pollute global namespace.
But I strongly suggest you to take a look with a modern approach using webpack which seems to be more popular within React and Flux community.
Related
I'm writing a node program and I want several functions contained in separate files to access and modify the same scope of variables without defining them in the global scope.
The solution I found is using a module to share its scope but it seems a bit tricky.
Here's the file tree :
- index.js
- file-a.js
- file-b.js
- shared-scope.js
index.js :
require('./file-a')
require('./file-b')
file-a.js :
const sharedScope = require('./shared-scope');
sharedScope.foo = 'bar'
file-b.js :
const sharedScope = require('./shared-scope');
console.log(sharedScope) // Prints { foo: 'bar' }
shared-scope.js :
module.exports = {};
What do you think about it? Is this a good way of sharing a scope between modules?
Sure, that's called a singleton. Some might say that any global, shared state is bad, but if that's what you want, this is a perfectly fine and simple way to do it.
The most obvious alternative is to define the data in one place and then in other modules, define functions which work on the data.
file-b.js:
module.exports = function (data) {
data.foo = "bar";
}
index.js:
const assignFoo = require('./file-b.js');
const data = {};
assignFoo(data);
So I've been playing with JS and browserify to allow to split my JS into smaller file chunks. It works great, however, I'm still lost on how to properly use the require function.
For me, it acts as a the Service Locator, because it looks for the proper "file" to load, and return an object. (For example in PHP, require somewhat load the file in the memory but doesn't construct).
Example:
var Foo = function() {
console.log("I'm the Foo object");
};
module.exports = Foo;
Then, to use it I'll do:
var Foo = require('foo');
and
var foo = new Foo();
Note, that the exported function is NOT constructed.
I could have done:
var foo = require('foo')();
None of those methods seems right to me (I may are wrong).
1) Is it common to do it like this? Or should exported the executed function?
Anyway, this introduction is to understand how I should play with the require function.
For example if I've a Foo object, which is depends of Bar, I've two way to do:
Service Location:
var Foo = function() {
var Bar = require('bar')();
Bar.doSomethingAwesome();
};
module.exports = Foo;
or I can do:
Dependency Injection
var Foo = function(bar) {
bar.doSomethingAwesome();
};
module.exports = Foo;
// And at a latter time
var foo = require('foo')(require('bar')); /// eurk
I obviously know that that's two different things and serve different purposes.
2) But I'm wondering what is the common/right way to do in JS, is there any commonly admitted rules?
Browserify allows you to program with modules, there's not much more to it. It's not really a DI container or service locator per se, although you can probably make it work like one.
So doing this is perfectly fine:
var Foo = require('foo');
var foo = new Foo();
In that case, it makes sense to simply place all require calls at the top of your file, similar like you would do with using in C# or import in Java. I personally wouldn't scatter require calls since don't help much with readability.
You can also export an instance which doesn't have to be newed up anymore, as long as that is appropriate for what you want to do (in that case module.exports = Foo() would lead to a singleton).
Also see this related question:
Dependency Injection with RequireJS
The rewire library provides module injection for Node.js.
A couple of solutions have been discussed and presented in this Github issue to support browserify.
Usage example from the project README:
var myModule = rewire("../lib/myModule.js");
myModule.__set__("fs", fsMock); // set private variable
Use Browserify so you can require npm packages from your browser just like node. Then you can use Weather.js or require it, then inject it in any way you like.
Disclaimer: I am using ExtJS 3, but I don't think it's very relevant to the question, outside of the common use of it's namespacing function.
I have a singleton that's declared in a really long namespace like this:
Ext.ns("REALLY.REALLY.LONG.NAMESPACE");
var Singleton = (function() {
var foo = {
bar: "baz"
};
var privateFunction = function(param){
// ...
return foo;
};
var single = Ext.extend(Object, {
constructor: function(config) {
Ext.apply(this, config);
},
otherFunction: privateFunction,
publicFunction: function (someObject){
// do stuff with someObject
}
});
return single;
})();
// Make it a singleton
REALLY.REALLY.LONG.NAMESPACE.Singleton = new Singleton();
I use it in other modules via calls like REALLY.REALLY.LONG.NAMESPACE.Singleton.otherFunction(); and REALLY.REALLY.LONG.NAMESPACE.Singleton.publicFunction(myObject); . I'm wondering if I can swap out those calls by setting up the client module with an alias to the singleton, i.e. var singleton = REALLY.REALLY.LONG.NAMESPACE.Singleton; , so that I can call singleton.otherFunction();. I'm wondering if this is an anti-pattern , or if there are any pitfalls (memory?) I might run into through this usage.
Thanks StackOverflow!
I'm wondering if I can swap out those calls by setting up the client module with an alias to the singleton
Yes, you can.
I'm wondering if this is an anti-pattern , or if there are any pitfalls (memory?) I might run into through this usage.
No, there aren't any that I can think of and it is faster than calling the fully-qualified version.
Local Alias Pattern
Example:
function somefunc(){
var singleton = REALLY.REALLY.LONG.NAMESPACE.Singleton;
singleton.publicFunction();
};
Or:
(function somfunc(singleton){
}(REALLY.REALLY.LONG.NAMESPACE.Singleton));
Test Results:
http://jsfiddle.net/jMg9A/
There is no issue with creating a reference to the original "object". In many cases we create a namespace to organize our code, but of course, this can lead to really long namespaces that we really don't wish to reference later, thus creating a local reference to that namespace is an excellent idea so that you can change it in one place instead of various places.
I don't really see an ant-pattern here, instead I see an opportunity to make it simpler for yourself and probably a little more manageable from a developer standpoint.
This is a JS newbie questions, I am working with a parent namespace Base and I include all my code within this namespace.
file model.js
Base = {}
Base.Observer = {
method1 : function(){//...},
method2 : function(){//...}
};
Base.Bot = function(name){
this.name = name;
this.somefunc = function(){};
}
file presenter.js
Base.Presenter = {
}
file helper.js
Base.Helper = { };
Now my problem is I would like to keep this module private. Without allowing any user access through any browser tools like firebug. So I could only think of wrapping them within a self executing anonymous function and making Base into a local variable which would lead to the presenter.js and helper.js not being able to access the Base namespace.
I would like to keep the files separate as it helps in keeping code organizated but I can't seem to figure what is the correct way to do this. Would appreciate any help on this.
Thank you
So I could only think of wrapping them within a self executing anonymous function and making Base into a local variable
That is the usual approach
which would lead to the presenter.js and helper.js not being able to access the Base namespace.
The function should return Base; which you then assign to a global.
See the module pattern
A while ago, I offered-up a JavaScript design pattern (the Module Pattern - see below) that I got from a John Resig example as part of a solution to someone’s question and I received the following comment:
“…that pattern is a bit over
engineered and not that good. Still
leaking into global-scope. and your
not opening yourself to async loaders.
But it is better then just ad-hoc
coding !”
So…
If “leaking” into global scope means “your object gets appended to the browsers window (object)”…then everything already gets appended (globally):
This “leaks” into global scope:
window.jQuery
…just call: window.jQuery and it resolves as a function();
This “leaks” into global scope:
function HelloWorld() { alert(‘Howdy’); }
…just call: window.HelloWorld() and you will get ‘Howdy’.
This “leaks” into global scope:
var myVariable = 10;
…just call: window.myVariable and you will get 10
If the commenter is correct, then all the above “leak” into global-scope. So, personally, I don’t see a way NOT to “leak” into global-scope as even your form controls exists there (as well).
As such, here are my questions…
What is meant by “leaking” into
global-scope?
Why is that bad?
How do you avoid it?
When wanting to create persistent
custom-objects, why is the Module
Pattern (below) bad?
Design patterns let you encapsulate
complex logic, is encapsulation
suddenly bad simply because we’re
writing in JavaScript?
Or...is this commenter simply wrong?
Here is the Module Pattern I Mentioned Above:
<script type="text/javascript">
var myNamespace = (function($) {
var publicInstances = {};
// ***********************
// myObject
publicInstances.myObject = myObject;
function myObject() {
/// <summary>A pointer to this</summary>
var self = this;
this.someProperty = new String();
this.initialize = function() {
/// your code here
}
this.someMethod = function() {
/// your code here
}
self.initialize();
}
return publicInstances;
})(jQuery);
jQuery(document).ready(function() {
// Use would look like
var myInstance = new myNamespace.myObject();
});
</script>
UPDATED:
I’m satisfied with the answers below and want to thank everyone for taking the time to comment.
TO RECAP THE ANSWERS BELOW:
"Leaking" into global-scope occurs when something used in local-scope is unintentionally made available to the global-scope (e.g. the window object). This is bad because it opens the page to potential naming collisions which could result in variables resolving to unexpected values or types.
Intentionally making a variable global is not considered a "leak". However, properly namespacing the object is required to reduce potential for said naming collisions.
You cannot avoid globally-scoped variables, but you can reduce the above risks by using asynchronous-loaders and defining-modules made available in plug-ins like RequireJS or Curl.
"Leaking" into global scope is when something used in a local scope is unintentionally made available to the global scope. That means assigning to a variable not already defined in the current scope:
function myFunction() {
a=1;
}
myFunction();
alert(a);
//-> 1
It's bad because there could be naming collisions resulting in variables with different values/types than expected. It can also lead to a bug in older Internet Explorers when you forget to use the var keyword for a variable used in a for statement.
I wouldn't class intentionally making a variable global as "leaking", because it's more like you're "pouring" it into the global scope. However, this is still often considered bad practice by some (although I think that's a little melodramatic) because there are still potential naming collisions with current properties of the window object, or variables set by other scripts and libraries.
[[Short story]]
Don't make global variables ever and use an async module loader like requirejs or curl
[[Long story]]
That comment was poorly structured.
There is nothing wrong with the module system. I was complaining about using global variables at all. (I still think the full generic module pattern is bloated).
Whether you should avoid all global variables is a different question and I think a matter of style. You can either use an async loader to pass modules around or using window to pass modules around.
What is meant by “leaking” into global-scope?
What I meant was your creating global variables. Minimising the use of global variables is a pattern. In functional style programming it's possible to have zero global variables but this is a different pattern from using global modules.
Why is that bad?
Having any state globally can cause that state to be corrupted.
How do you avoid it?
You can't. You can minimize the amount of global variables though. To avoid having global state completely you can use asynchronous loaders. These define a few global variables for you that you can then use.
When wanting to create persistent custom-objects, why is the Module Pattern (below) bad?
There is nothing wrong with the module pattern. The problem is storing your module globally. The issue is having global namespaces.
Design patterns let you encapsulate complex logic, is encapsulation suddenly bad simply because we’re writing in JavaScript?
Now that I've cleared up the intent of the comment this question isn't really relevant
Or...is this commenter simply wrong?
The comment was poorly phrased at best. I objected to global namespaces rather than modules, but did not state this properly.
The alternative is using asynchronous loaders and defining modules. These can be narrowed down to two global variables. define and require.
require = function(moduleName, callback)
This will get a module and then return it to you.
define = function(obj)
this defines a module.
The concept here is that you multi file code as follows:
// main.js
require([
"foo.js",
"bar.js",
...,
], function(foo, bar, ...) {
// do stuff
});
//foo.js
(function() {
var namespace = modulePatternCode;
...
define(namespace):
})();
//bar.js
(function() {
var namespace = modulePatternCode;
...
define(namespace):
})();
Your module only "leaks" it's namespace holder so it's pretty acceptable.
Loader example using RequireJS:
Define a utilities module in utils.js:
define(function () {
return {
each: function (iterable, callback) {
// ...
},
map: function (iterable, mapper) {
// ...
}
};
});
Use the above module in another module, say math.js:
define([ "utils" ], function (utils) {
return {
sum: function (numbers) {
var sum = 0;
utils.each(numbers, function (n) {
sum += n;
});
return sum;
},
average: function (numbers) {
return this.sum(numbers) / numbers.length;
}
};
});
And you can use math.js in another file, say main.js:
console.log("About to add 1-3");
require([ "math" ], function (math) {
console.log(math.sum([ 1, 2, 3 ]));
});
You can still have namespaces, and still keep them warm and cozy inside modules:
namespace.js:
define([ "foo", "bar", "moo" ] function (foo, bar, moo) {
return {
foo: foo,
bar: bar,
moo: moo
};
});
Then the rest of the modules can use this namespace during definition:
define([ "namespace" ], function (namespace) {
namespace.foo(42);
});
Or at runtime, in some other module:
define(function () {
return {
initialize: function () {
require([ "namespace" ], function (namespace) {
namespace.foo(42);
});
}
};
});
In the usages above, nothing but define and require are global. Of course, these are just illustrative examples, as there are many different flavors of defining/using modules in RequireJS.