This question already has answers here:
Why isn't my JavaScript working in JSFiddle?
(7 answers)
Closed 7 years ago.
I need to pass a list of variable names in JavaScript and check if those variables exist. I tried the following but it doesn't seem to be doing the trick (JSFiddle here):
var test1 = 'test1';
var test2 = 'test2';
function checkVariable(variableNameList) {
for (var iterator = 0; iterator < variableNameList.length; iterator++) {
var variableName = variableNameList[iterator];
if (typeof window[variableName] === 'undefined') {
alert('Variable ' + variableName + ' is not defined');
} else {
alert('Variable ' + variableName + ' is defined');
}
}
}
checkVariable(['test1', 'test2', 'test3']);
I'm trying to get the resulting alerts:
Variable test1 is defined.
Variable test2 is defined.
Variable test3 is not defined.
It seems easy to fix using the trick below but is there any other way to achieve this? Is declaring global variables under window the only way to track them?`
window.test1 = 'test1';
window.test2 = 'test2';
Are there better ways to do this or is this the right approach?
Vanilla JS only answers please.
It does not work because the variables are not in global scope, they are in scope of the window.onload function scope.
Your code is actually running like this:
window.addEventListener("load", function () {
var test1 = 'test1'; /* these are not global because of */
var test2 = 'test2'; /* running inside of window.onload */
function checkVariable(variableNameList) {
}
checkVariable(['test1', 'test2', 'test3']);
});
Change your code to run either in the head or at the end of the body. I forked your code to run in the head: https://jsfiddle.net/phrhxyzL/1/ and you get the results you expect.
Related
This question already has answers here:
What does 'var that = this;' mean in JavaScript?
(6 answers)
Closed 3 years ago.
I've seen things like this:
function fnx(){
ctrl = this;
this.thisedVar = "thisedVar from fnx"
}
I'm trying to figure out what is it useful for. if that function is executed and then this is compared to ctrl, they are the same:
fnx();
console.log(this === ctrl) // true
That's why I don't understand what is the purpose of assigning this to a variable.
Can anyone explain it, please? Thanks.
var a = function() {
var THIS = this;
this.s = "Hello World";
this.runMe = function() {
window.setTimeout(function() {
console.log(this.s);
}, 100);
}
}
var a2 = function() {
var THIS = this;
this.s = "Hello World";
this.runMe = function() {
window.setTimeout(function() {
console.log(THIS.s);
}, 100);
}
}
b = new(a);
b.runMe();
b2 = new(a2);
b2.runMe()
Outputs:
undefined
Hello World
Class a (object b) returns undefined because that this is in the scope of the callback.
Class a2 (object b2) returns Hello World because that this belongs to the class a2.
When you assign a variable to a value without using var it refers to global variable. So if you are assigning this to ctrl it means the your are assigning Window obecjt this to a global variable `ctrl.
So when you compare ctrl with this (again Window) object, it is same since you are matching after function execution.
In most cases, the value of this is determined by how a function is called (runtime binding). It can't be set by assignment during execution, and it may be different each time the function is called.
You assign THIS to a variable so you save this value.
Read more: https://medium.com/tech-tajawal/javascript-this-4-rules-7354abdb274c
This question already has answers here:
How does hoisting work if JavaScript is an interpreted language?
(2 answers)
Are variables declared with let or const hoisted?
(7 answers)
Closed 4 years ago.
In most languages I would write
declare var1 = undefined
if (condition) {
var1 = value1
}
but in javascript, it seems its allowed to write
if (condition) {
let var1 = value1
} else {
var1 = value2
}
Am I misguided on this?
Yes you can when you use var.
Not when you use let and const because they are block scoped.
Example for var
if (true) {
var var1 = 1
}
console.log(var1);
Example using let
if (true) {
let var1 = 1;
}
console.log(var1)
P.S :- In JS world using var is considered as bad coding practice.You should avoid using it until there is something you can't do with let and const.
In JavaScript, a variable can be declared after it has been used.
In other words: a variable can be used before it has been declared.
Hoisting is JavaScript's default behavior of moving all declarations to the top of the current scope (to the top of the current script or the current function).
So:
x = 5
// ... some other code ...
var x
will be translated to:
var x;
x = 5
// ... some other code
But it would only work this way if you used var to declare variable. If you use const or let it wouldn't work, because variables and constants declared with let or const are not hoisted.
Declaring variables using let or const is preferred way in modern javascript.
No, it's completely bad idea. If you want to use JavaScript variable both inside and outside of the if statement you can do it by declaring it outside the if statement.
let var1 = value1;
if (condition) {
var1 = value1
} else {
var1 = value2
}
This way you will only create a block scoped variable. But, if you use var var1 = value1 then it will declare globally scoped variable which is not what you wanted most probably.
To learn more about how variables works in javascript, you can checkout this awesome article. Happy coding :)
You can do this using let, but NOT in Strict Mode!
'use strict';
var condition = false;
if (condition) {
let var1 = 42;
console.log(var1);
} else {
var1 = 43;
console.log(var1);
}
// ReferenceError: var1 is not defined
It's recommended to declare var1 outside the scope of if statement:
'use strict';
var condition = false;
var var1 = 42;
if (condition) {
console.log(var1);
} else {
var1 = 43;
console.log(var1);
}
// => 43
I was wondering if there is any way to access variables trapped by closure in a function from outside the function; e.g. if I have:
A = function(b) {
var c = function() {//some code using b};
foo: function() {
//do things with c;
}
}
is there any way to get access to c in an instance of A. Something like:
var a_inst = new A(123);
var my_c = somejavascriptmagic(a_inst);
A simple eval inside the closure scope can still access all the variables:
function Auth(username)
{
var password = "trustno1";
this.getUsername = function() { return username }
this.eval = function(name) { return eval(name) }
}
auth = new Auth("Mulder")
auth.eval("username") // will print "Mulder"
auth.eval("password") // will print "trustno1"
But you cannot directly overwrite a method, which is accessing closure scope (like getUsername()), you need a simple eval-trick also:
auth.eval("this.getUsername = " + function() {
return "Hacked " + username;
}.toSource());
auth.getUsername(); // will print "Hacked Mulder"
Variables within a closure aren't directly accessible from the outside by any means. However, closures within that closure that have the variable in scope can access them, and if you make those closures accessible from the outside, it's almost as good.
Here's an example:
var A = function(b) {
var c = b + 100;
this.access_c = function(value) {
// Function sets c if value is provided, but only returns c if no value
// is provided
if(arguments.length > 0)
c = value;
return c;
};
this.twain = function() {
return 2 * c;
};
};
var a_inst = new A(123);
var my_c = a_inst.access_c();
// my_c now contains 223
var my_2c = a_inst.twain();
// my_2c contains 446
a_inst.access_c(5);
// c in closure is now equal to 5
var newer_2c = a_inst.twain();
// newer_2c contains 10
Hopefully that's slightly useful to you...
Answers above are correct, but they also imply that you'll have to modify the function to see those closed variables.
Redefining the function with the getter methods will do the task.
You can do it dynamically.
See the example below
function alertMe() {
var message = "Hello world";
console.log(message);
}
//adding the getter for 'message'
var newFun = newFun.substring(0, newFun.lastIndexOf("}")) + ";" + "this.getMessage = function () {return message;};" + "}";
//redefining alertMe
eval(newFun);
var b = new alertMe();
now you can access message by calling b.getMesage()
Of course you'll have to deal with multiple calls to alertMe, but its just a simple piece of code proving that you can do it.
The whole point to that pattern is to prevent 'c' from being accessed externally. But you can access foo() as a method, so make it that it will see 'c' in its scope:
A = function(b) {
var c = function() {//some code using b};
this.foo = function() {
return c();
}
}
No, not without a getter function on A which returns c
If you only need access to certain variables and you can change the core code there's one easy answer that won't slowdown your code or reasons you made it a closure in any significant way. You just make a reference in the global scope to it basically.
(function($){
let myClosedOffObj = {
"you can't get me":"haha getting me would be useful but you can't cuz someone designed this wrong"
};
window.myClosedOffObj = myClosedOffObj;
})(jQuery);
myClosedOffObj["you can't get me"] = "Got you now sucker";
Proof of concept: https://jsfiddle.net/05dxjugo/
This will work with functions or "methods" too.
If none of the above is possible in your script, a very hacky solution is to store it in a hidden html-object:
// store inside of closure
html.innerHTML+='<div id="hiddenStore" style="display:none"></div>';
o=document.getElementById("hiddenStore")
o.innerHTML="store this in closure"
and outside you can read it with
document.getElementById("hiddenStore").innerHTML
You should be able to use an if statement and do something like:
if(VaraiableBeingPasses === "somethingUniqe") {
return theValueOfC;
}
This question already has answers here:
dynamically call local function in javascript
(5 answers)
Closed 8 years ago.
I'm having a difficulty calling a function inside of another function when its name is in a variable:
var obj = {}
obj.f = function() {
var inner = {
a: function() {
function b() {
alert('got it!');
}
b(); // WORKS AS EXPECTED
x = 'b';
[x](); // DOESN'T WORK, NEITHER this[x]() window[x](), etc.
}
}
inner.a();
}
obj.f();
I tried prefixing [x]() with different scope paths but so far w/o success. Searching existing answers did not turn up anything. It works with this[x]() if b() is placed directly inside object inner. I would like to keep b() as a function inside function a() because of variable scope in function a(), otherwise I would need to pass many parameters to b().
////
Re duplicate question: Quentin provided a more elegant answer in this thread imo.
There is no sensible way of accessing an arbitrary variable using a string matching the name of the variable. (For a very poor way to do so, see eval).
[x](); // DOESN'T WORK
You're trying to call an array as a function
NEITHER this[x]()
The function isn't a property of the inner object.
window[x](), etc.
Since it isn't a global, it isn't a property of the window object either.
If you need to call a function based on the value of a string variable, then organise your functions in an object and access them from that.
function b() {
alert('got it!');
}
var myFunctions = {
b: b
};
x = 'b';
myFunctions[x]();
Try this. Currently you are assigning string to variable x, instead of a function variable.
x = b;
x();
The problem is with your assignment
use x = b instead of x = 'b' to assign the function object as the latter just assigns the string into x.
Once you fix your assignment you can invoke the function as
x();
a.x();
a[x]();
etc.
You should make array for the function and then access using name in your variable as follow:
var obj = {}
obj.f = function() {
var inner = {
a: function() {
// set up the possible functions:
var myFuncs = {
b: function b() {alert('got it!');}
};
//b(); // WORKS AS EXPECTED --> commented this code
x = 'b';
myFuncs[x]();
}
}
inner.a();
}
The function declaration b will be captured in the closure of the anonymous function expression assigned as a.
When var is used in a closure, there is no (available in JavaScript) Object which gets assigned a property similar to what happens with window in the Global Scope.
Writing a function declaration effectively vars the name of the function.
If you really want to access a variable (i.e. b) by String, you will either need to create an Object which holds b similar to what you've done for a, or (and possibly dangerously) rely on an eval to convert "b" to b.
If you can't create the whole Object ahead-of-time, you can use this format
/* in (higher?) scope */
var fnRef = {};
// now when you
function b() {/* define as desired */}
// also keep a ref.
fnRef['b'] = b;
// fnRef['b']() will work **after this line**
let's say your code is like this:
//instead of x = 'b'
x = function(){}
then your solution could be like this:
var obj = {}
obj.f = function() {
var inner = {
a: function() {
function b() {
alert('got it!');
}
b(); // WORKS AS EXPECTED
//you can define it as a variable
var x = function(){};
//and call it like this
x();
//or define it like this
this[x] = function(){};
//and call it like this
this[x]();
//but you are creating an array [x] which is not a function
//and you are trying to call an array????
[x](); // DOESN'T WORK, NEITHER this[x]() window[x](), etc.
}
}
inner.a();
}
obj.f();
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What do parentheses surrounding a JavaScript object/function/class declaration mean?
I have found the following code in a website .
var testModule = (function(){
var counter = 0;
return {
incrementCounter: function() {
return counter++;
},
resetCounter: function() {
console.log('counter value prior to reset:' + counter);
counter = 0;
}
};
})();
So it follows the syntax var a = (blah balh..)()
What does it actually mean? What is the meaning of variable declaration like a =()()..
It's defining a single-use function and executing it immediately. The code you provided is named the Module Pattern -- see here for more information about its properties: http://www.yuiblog.com/blog/2007/06/12/module-pattern/
A normal function might be created like this:
var f1 = function() {
console.log('bar');
};
And you could subsequently call it like so:
f1();
But in the example you provided, the function is both defined and executed once, and that function returns an object with two functions: incrementCounter and resetCounter. You can call them like so: testModule.incrementCounter() and testModule.resetCounter()
The Module Pattern is useful when you have a single object and you want to encapsulate some properties which are only available to the functions defined in the closure.
The anonymous function is executed and the return value is assigned to the variable.