This may be very simple but i lost my way in finding the answer,
I have a named function inside a Backbone view. I'm trying to write unit test for this named function and i could see a variable is being declared in function scope. The state of this variable changes based on certain scenarios.
I have instantiated the view object inside my test suite and when i do a console.log(viewObject.namedFunction) i see the entire function being logged properly. Now how do i access the variable inside the namedFunction, i was expecting something like viewObject.namedFunction.variableName but it will not work and when i did that, it was not working as expected.
If the variable is tied to viewObject scope then it would have been easy to access it. But in this scenario it is not so can some one please help me in getting a hold on the variable inside named function in view object from test suite.
I think I understand your confusion, because when you define a variable using var in the window scope, it becomes a property on the window object... It would seem to follow that when you define a variable in a child scope, it should become a member of the local context, right? Nope. Globals are special ;-)
In fact, if that were the case, there would be no privacy!
If you want sign to be public, be explicit.
obj = {
namedFunction : function myself() {
console.log(myself);
myself.sign = 23;
}
};
obj.namedFunction.sign;
The only problem with this approach is that you can now assign a new value to sign from anywhere. The classic and preferred approach to this problem is to create a getter function for your private variable.
var obj = {
namedFunction : function myself() {
var sign = 3;
myself.getSign = function(){return sign;};
}
};
obj.namedFunction.getSign();
This isn't by any means the only approach, but I hope it was helpful.
One way to do this is like such:
namedFunction = (function(){
var theActualFunction = function(){
//Do something
//Access variable like: theActualFunction.MyVariable
};
theActualFunction.MyVariable = "value";
return theActualFunction;
}());
Related
I want to access the variable with the "apfala"
var frucht="apfala";
function getFrucht(frucht){
console.log(frucht);
console.log(this.frucht) // I want here the apfala one, I thought .this would work
}
getFrucht("apfel");
Or do I have to rename them differently?
http://eslint.org/docs/rules/no-shadow
Shadowing is the process by which a local variable shares the same
name as a variable in its containing scope. For example:
var a = 3;
function b() {
var a = 10;
}
In this case, the variable a inside of b() is shadowing the variable a
in the global scope. This can cause confusion while reading the code
and it’s impossible to access the global variable.
Your code suggests that you need to rethink whatever it is you are trying to do. As it is unclear as to the true nature of what you are trying to do, it is hard to suggest an alternative solution to your problem (other than do not shadow or use globals), if you have one rather than just curiosity?
Please don't do this, but this should work in all environments.
'use strict';
var getGlobal = Function('return this');
getGlobal().frucht = 'apfala';
function getFrucht(frucht) {
console.log(frucht);
console.log(getGlobal().frucht); // I want here the apfala one, I thought .this would work
}
getFrucht('apfe');
Also see: https://www.npmjs.com/package/system.global
In case your javascript runs in a browser, you can use the window global variable in order to access the variable frucht that defined in the global scope:
var frucht="apfala";
function getFrucht(frucht){
console.log(frucht);
console.log(window.frucht) // I want here the apfala one, I thought .this would work
}
getFrucht("apfel");
If it is a global and you are running in a browser:
You can use window.frucht as global variables are properties of the window object.
Not reusing the same variable name would be a much better idea though. It avoids the dependency on globals and the confusing of reusing names.
Generally speaking, in JavaScript, if you want to pass a parent scope to a child one, you need to assign this in the parent to a variable and access that variable inside the child:
var frucht="apfala";
var parent = this;
function getFrucht(frucht){
console.log(frucht);
console.log(parent.frucht);
}
getFrucht("apfel");
Also, as stated in other answers, if you are working in a browser, just use the window object to attach and access global variables (window.frucht="apfala", then use window.frucht to access that variable)
Hope that helps.
I have a function with lots of variables and very big arrays being defined; this makes the function very large and hard to work with. How can I define the variables/arrays in another file and use them in this function?
Example:
DoStuff.js:
function genList(){
var listData = [
//lots of inner arrays and data
]
var dataItem = "value";//50 of these
//do stuff with the data
}
What I'm trying to do:
ExternalData.js:
var listData = [
//lots of inner arrays and data
]
var dataItem = "value";//50 of these
DoStuff.js:
function genList(){
//call variables/arrays from ExternalData.js
//do stuff
}
Note:
JQuery is applicable here, but I'd rather not call any other libraries for something so small.
I would define all the variables in an object for example:
var obj = {
array_one: ['x', 'y'],
some_value: 'z'
}
This method has the advantage of make a kind of namespace for all the variables, saving you from overriding values.
And then use that object into my code using some kind of include method.
One simple method could be to add the script before the one you are writing like this:
<script type="text/javascript" scr="file_with_object.js"></script>
Other more sophisticated but only advisable if you are going to repeat this kind of behavior
is to use a Library or a framework to make includes more concise, require.js is a good example
EDIT: In the previous example I used the object with var considering that the code was written on the global scope, I think it would be better to use window.obj = {} to ensure the variable is global. And, just for the record, any variable you define like this window.somevariable is going to be a global variable. Once you define a global variable you could use it anywhere in your code (after the definition takes place). The namespace is the right way to go though.
EDIT 2: I think this post is more about scope than includes. When you declare a variable this way: var some_variable; you are saying that you want to bind that variable to the current scope. So if you do that inside a function, that variable "lives" inside that function:
var some_var = 10;
function(){
var some_var = 5;
console.log(some_var) // 5
}
console.log(some_var) // 10
But if you declare the variable without the var on both cases you are making that varaible global the first time and overriding its value on the second:
some_var = 10;
function(){
some_var = 5;
console.log(some_var) // 5
}
console.log(some_var) // 5
And alway you declare a varaible without the var, that variable is accessible trough window.variablename, because you are not binding the variable to any particular scope, so the binding is made to the window objecy, which is the global scope "namespace".
(Maybe) I just solved a my problem (How to update front-end content after that a form is successfully submitted from a dialog window?) by "storing" / "saving" a variable in the JavaScript window object. However, since I am newbie in JavaScript matters, I have some doubts if storing / saving a variable in the JavaScript window object is a "common" / "proper" way to use that object. Is it?
For example, using the following code
$('.trigger').click(function() {
window.trigger_link = this;
});
is advisable?
In JavaScript, any global variable is actually a property of the window object. Using one is equivalent to (and interchangeable with) using the other.
Using global variables is certainly "common," so the question is whether or not it's "proper." Generally, global variables are discouraged, because they can be accessed from ANY function and you risk having multiple functions trying to read from and write to the same variables. (This is true with any programming language in any environment, not just JavaScript.)
Solve this problem by creating a namespace unique to your application. The easiest approach is to create a global object with a unique name, with your variables as properties of that object:
window.MyLib = {}; // global Object container; don't use var
MyLib.value = 1;
MyLib.increment = function() { MyLib.value++; }
MyLib.show = function() { alert(MyLib.value); }
MyLib.value=6;
MyLib.increment();
MyLib.show(); // alerts 7
Another approach is to use .data() to attach variables to a relevant DOM element. This is not practical in all cases, but it's a good way to get variables that can be accessed globally without leaving them in the global namespace.
What is actually not mentioned here, and is probably the biggest deal breaker on why not to use window as global scope carrier is that it can be frozen (not writable) in some cases (and I'm talking from production based experience).
A good pattern is actually just create a global variable that will be used for all the common stuff in your application
var Application = {};
Application.state = { name: 'Application' }
.
.
What I found as the best pattern for me in javascript is to have a global state using Redux.
Another pattern to make a unique namespace in your application.
(function myApp()
{
var value = 5;
function addToValue(x)
{
value += x;
}
})()
If you want functions/values to be accessible afterwards you can store them in an object like this:
function myApp()
{
this.value = 5;
this.addToValue = function(x)
{
this.value += x;
}
}
var myInstance = new myApp();
I have tried to figure this out or search for it on google, i can only find how to create objects, not exactly how functions work. If someone could explain to me how encapsulation works.
function myObject() {
this.variable1 = "tst";
this.function1 = function() {
//Now this function works. A 'this' function to a private function is ok
_PrivateFunction1();
//Here is error one, I cannot seem to call methods within the object
//from.
this.function2();
}
this.function2 = function() {
alert("look! function2!");
}
function _PrivateFunction1() {
//This does work though. I am confused.
_PrivateFunction2();
}
function _PrivateFunction2() {
alert("look! PrivateFunction1");
//this does not work.
alert(this.variable1);
}
}
I think I can explain this better if we go in reverse order. First, we define some functions:
function _PrivateFunction1() {
//This does work though. I am confused.
_PrivateFunction2();
}
function _PrivateFunction2() {
alert("look! PrivateFunction1");
//this does not work.
alert(this.variable1);
}
This is pretty normal stuff. The only thing that's weird is that they appear inside another function, but that's perfectly fine. JavaScript has function scope, which means that all variables defined inside a function are defined in a new scope. They do not trample on the global namespace. And functions are first-class objects in JavaScript, which means they can be used just like other data types. They can be nested, passed to functions, returned from functions, etc.
Then we run into some trouble:
function _PrivateFunction2() {
alert("look! PrivateFunction1");
//this does not work.
alert(this.variable1);
}
}
Functions in JavaScript are always executed in some context which is referred to by the this keyword. When you call a function directly (i.e. like this: functionName()) the context in which that function executes is the global window object. So, inside _PrivateFunction2, this.variable1 is equivalent to window.variable1 which is probably not what you meant.
You probably wanted to refer to the current instance of myobject which is what this refers to outside of _PrivateFunction2. You can preserve access to this in an inner scope by storing a reference to it in another variable:
var _this = this;
function _PrivateFunction2() {
alert("look! PrivateFunction1");
//this does not work.
alert(_this.variable1);
}
There's something subtle here you should notice. _PrivateFunction2 has access to the variables defined in its lexical scope, which is why it can access _this. This will be important later.
Next up:
function _PrivateFunction1() {
//This does work though. I am confused.
_PrivateFunction2();
}
This should be the most normal-looking section to you, I would think. There's nothing strange going on here. Just one regular function calling another one. Don't be confused by the fact that these are nested inside myObject. That changes the scope they're in, but not much else.
Next we define some instance variables and methods:
this.variable1 = "tst";
this.function1 = function() {
//Now this function works. A 'this' function to a private function is ok
_PrivateFunction1();
//Here is error one, I cannot seem to call methods within the object
//from.
this.function2();
}
this.function2 = function() {
alert("look! function2!");
}
Here this really does refer to myObject, assuming -- and it's an important assumption -- that myObject was called with the new operator, like this:
var obj = new myObject();
If it had been called like this:
var obj = myObject();
Then this would refer to the window object, just like it did for the functions we saw earlier. The key takeaway is that the value of this is not fixed. It's determined by the way in which the function is called. There are even ways to set it to an arbitrary object explicitly.
The value of this inside this.function1 will also be the current instance of myObject, because it will most likely be used like this:
var obj = new myObject();
obj.function1();
Writing object.method() sets this to object inside method.
So how is this.function1 able to call _PrivateFunction1()? Just as we saw earlier when saving the value of this for use inside a nested function, _PrivateFunction1() is just another object defined in this.function1's lexical scope, so it is available for its use, just as _this was earlier.
And it's because of closure that these private variables are still alive long after myObject has returned.
Footnote: Because failing to use new when instantiating objects breaks things so spectacularly without warning, it's considered good practice to capitalize the names of functions you intend to be used as a constructor. So myObject should really be MyObject.
You have to save a copy of the actual object like here note the var that = this
Tested in chrome and FF
for encapsulation I would prefer module pattern like
var someMethod = function(){
var i,
length,
// public method
public = function(num1, num2){
return num1+num2;
},
//private method
_private = function(){};
//exposing the public method
return{
public:public
}
};
var callPublic = someMethod();
callPublic.public(20, 30);// call the public method and return 50
now , if you try to call that private method like
callPublic._private();//it will return not a function since its not been exposed
There are lot of other pattern to encapsulate your methods but module pattern is most common. Hope ot will help you how to encapsulate data in javascript.
I've heard from a variety of places that global variables are inherently nasty and evil, but when doing some non-object oriented Javascript, I can't see how to avoid them. Say I have a function which generates a number using a complex algorithm using random numbers and stuff, but I need to keep using that particular number in some other function which is a callback or something and so can't be part of the same function.
If the originally generated number is a local variable, it won't be accessible from, there. If the functions were object methods, I could make the number a property but they're not and it seems somewhat overcomplicated to change the whole program structure to do this. Is a global variable really so bad?
I think your best bet here may be to define a single global-scoped variable, and dumping your variables there:
var MyApp = {}; // Globally scoped object
function foo(){
MyApp.color = 'green';
}
function bar(){
alert(MyApp.color); // Alerts 'green'
}
No one should yell at you for doing something like the above.
To make a variable calculated in function A visible in function B, you have three choices:
make it a global,
make it an object property, or
pass it as a parameter when calling B from A.
If your program is fairly small then globals are not so bad. Otherwise I would consider using the third method:
function A()
{
var rand_num = calculate_random_number();
B(rand_num);
}
function B(r)
{
use_rand_num(r);
}
Consider using namespaces:
(function() {
var local_var = 'foo';
global_var = 'bar'; // this.global_var and window.global_var also work
function local_function() {}
global_function = function() {};
})();
Both local_function and global_function have access to all local and global variables.
Edit: Another common pattern:
var ns = (function() {
// local stuff
function foo() {}
function bar() {}
function baz() {} // this one stays invisible
// stuff visible in namespace object
return {
foo : foo,
bar : bar
};
})();
The returned properties can now be accessed via the namespace object, e.g. ns.foo, while still retaining access to local definitions.
What you're looking for is technically known as currying.
function getMyCallback(randomValue)
{
return function(otherParam)
{
return randomValue * otherParam //or whatever it is you are doing.
}
}
var myCallback = getMyCallBack(getRand())
alert(myCallBack(1));
alert(myCallBack(2));
The above isn't exactly a curried function but it achieves the result of maintaining an existing value without adding variables to the global namespace or requiring some other object repository for it.
I found this to be extremely helpful in relation to the original question:
Return the value you wish to use in functionOne, then call functionOne within functionTwo, then place the result into a fresh var and reference this new var within functionTwo. This should enable you to use the var declared in functionOne, within functionTwo.
function functionOne() {
var variableThree = 3;
return variableThree;
}
function functionTwo() {
var variableOne = 1;
var var3 = functionOne();
var result = var3 - variableOne;
console.log(variableOne);
console.log(var3);
console.log('functional result: ' + result);
}
functionTwo();
If another function needs to use a variable you pass it to the function as an argument.
Also global variables are not inherently nasty and evil. As long as they are used properly there is no problem with them.
If there's a chance that you will reuse this code, then I would probably make the effort to go with an object-oriented perspective. Using the global namespace can be dangerous -- you run the risk of hard to find bugs due to variable names that get reused. Typically I start by using an object-oriented approach for anything more than a simple callback so that I don't have to do the re-write thing. Any time that you have a group of related functions in javascript, I think, it's a candidate for an object-oriented approach.
Another approach is one that I picked up from a Douglas Crockford forum post(http://bytes.com/topic/javascript/answers/512361-array-objects). Here it is...
Douglas Crockford wrote:
Jul 15 '06
"If you want to retrieve objects by id, then you should use an object, not an
array. Since functions are also objects, you could store the members in the
function itself."
function objFacility(id, name, adr, city, state, zip) {
return objFacility[id] = {
id: id,
name: name,
adr: adr,
city: city,
state: state,
zip: zip
}
}
objFacility('wlevine', 'Levine', '23 Skid Row', 'Springfield', 'Il', 10010);
"The object can be obtained with"
objFacility.wlevine
The objects properties are now accessable from within any other function.
I don't know specifics of your issue, but if the function needs the value then it can be a parameter passed through the call.
Globals are considered bad because globals state and multiple modifiers can create hard to follow code and strange errors. To many actors fiddling with something can create chaos.
You can completely control the execution of javascript functions (and pass variables between them) using custom jQuery events....I was told that this wasn't possible all over these forums, but I got something working that does exactly that (even using an ajax call).
Here's the answer (IMPORTANT: it's not the checked answer but rather the answer by me "Emile"):
How to get a variable returned across multiple functions - Javascript/jQuery