I want string convert to variable:
var abc='b';
var b=5;
console.log(window[abc]);
in js, above is normal. when use jquery:
$(document).ready(function(){
var abc='b';
var b=5;
console.log(window[abc]);
});
show is undefined, so, how can I write? In second example, gain 5 through global object.
var abc is defined within a function. So it's a 'local' variable, which isn't in the window object. Just use console.log(abc) and it'll be fine. In your first example console.log(abc) will work as well.
It's all about scopes.
var b = 5;
Exists only in scope of your function(){ ... }, but you are trying to look for it in scope of window.
try this instead:
console.log(eval(abc))
or, assign b as a key to some temp object:
$(document).ready(function(){
var scope = {};
scope.abc = 'b';
scope.b = 5;
console.log(scope[scope.abc])
});
UPDATE
In case you want to use local scope, just replace "scope" with "this":
$(document).ready(function(){
this.abc = 'b';
this.b = 5;
console.log(this[this.abc])
});
For quick example:
$(document).ready(function(){
var abc = 'b';
this.b = 5;
console.log(this[abc]);
});
Related
(function(){
var a = {};
a.b = function(){
alert('this is b');
}
}());
How to make the 'a' object as public in above code without removing 'var', means 'a' can access even from another file like below.
(function(){
a.b();
}());
Note: Dont say to remove 'var', i know that way. But i want to is their any other way that without removing 'var'.
You can attach it to the global scope. In web browsers, this is the window object.
window.a = {};
Later on, you can reference it by window.a or just a.
This is generally discouraged though as collisions can occur when two unassuming scripts run and define the same thing. It would be much better to wrap whatever you need in closures.
You can return a from the IIFE:
var a = (function(){
var a = {};
a.b = function(){
alert('this is b');
}
return a;
}());
or create a property to window:
(function(){
var a = {};
a.b = function(){
alert('this is b');
}
window.a = a;
}());
Is it possible to call the same name variables which set outside of the function?
var a = $(window).width(); // I want to call this variable
if(!$.isFunction(p)){
var a = $(window).height(); // Not this one
alert(a);
}
FIDDLE
In this case, you have actually redefined the value of a. There is absolutely no way of referencing a different variable with the same name, as it just acts as a redefinition.
If you want to declare a global variable you can do so by
window.varname="This is a global variable";
And you can access the same by
alert(window.varname);
Now you can also have a local variable inside a function with the same name
var varname="This is a local variable";
And you can access it normally.
Here's your code so that you can access the global variable not the local one.
var p = ['foo',''];
window.a = $(window).width();
if(!$.isFunction(p)){
var a = $(window).height();
alert(window.a);
}
In a code snippet such as yours, the variable a is being redefined. This is because an if statement doesn't create another scope for variables. However, functions do.
In a case like this:
var a = 0; // global
function doStuff() {
var a = 10; // local
alert(a);
alert(window.a)
}
alert(a);
doStuff();
alert(a);
inside the function doStuff, the variable a is being redefined. This snipped will therefore alert the numbers 0, 10, 0, 0. This proves that the global variable is not redefined inside the function, as printing a after calling doStuff doesn't change the value of a in the global scope.
The variable a outside of the function can be accessed, as any variable not declared in a non-global scope is placed inside the window object. However, if using this snippet (which calls an anonymous function, creating a new scope):
var a = 0; // global
function doStuff() {
var a = 10; // local
alert(a);
alert(window.a)
function() {
var a = 20; // even more local
alert(a);
alert(window.a);
}();
}
alert(a);
doStuff();
alert(a);
you cannot access the value of a inside the doStuff function. You can still access the global variable using window.a.
In your case, however, the if statement does not create a new scope, therefore you are redefining the variable a to the new value $(window).height().
Example:
var a=10;
if(true){
var a=5;
}
alert(a)// it will return a=5;
var a=10;
var a=5;
//both are same way assign value
In js if statement is not scope it visible every where with in function . you have to change the variable name
There is no blockscope in JavaScript (at least up until ES6).
Like you seem to expect from the if block. See
What is the scope of variables in JavaScript?
for an excellent summary of scopes that do exist in JavaScript.
Beware of Hoisting
Furthermore, you shouldn't sprinkle your var declarations through your code, but explicitly put them in the top of your function. That is where Javscript will hoist them anyway:
# so if you have a function like this
var i = 5;
function testvar () {
alert(i);
var i=3;
}
testvar();
# the alert window will contain undefined.
# because internally, it's been changed into this:
var i = 5;
function testvar () {
var i;
alert(i);
i=3;
}
testvar();
Minimize use of the global scope
Read
What is meant by “leaking” into global scope?
And listen to what Doug Crockford has to say about it. Actually, take an hour and watch the whole talk.
You can do it like this:
var p = ['foo',''];
var a = $(window).width(); // I want to call this variable
if(!$.isFunction(p)){
(function(b){
var a = $(window).height();
alert(b);
})(a);
}
No need to use the global scope, just create an anonymous function and call it with a as the argument. Inside the function b is a reference to the a variable outside the function.
It is a good practice not to modify the window object in javascript to write clean and maintainable code.
Less bugs and problems. I mean, never do the window.a thing. Is evil for your code.
No, you can't because of you have redefined the variable name in the same scope and beacuse of the hoisted variables your code will be interpreted by javascript in the following mode:
var p, a;
p = ['foo',''];
a = $(window).width(); // I want to call this variable
if(!$.isFunction(p)){
a = $(window).height(); // Not this one
alert(a);
}
Now you can easly see that the variable a will be replaced and not created
JavaScript has two scopes: global and local. In your example a is in the global scope both times so you are just redefining it.
However you can specify skip a variable in local scope and get the one from global. Consider this example:
var a = 1;
function foo () {
var a = 2;
console.log("var a is: " + window.a);
console.log("local var a is: " + a);
}
foo ();
Will log "var a is: 1"\n"local var a is: 2\n" to the console. This is about as close as it gets to what you need
var abc = new Array();
abc[0] = 'str1';
abc[1] = 'str2';
Use array in this case
Try this (pattern)
var p = ['foo', ''];
var a = function (name) {
return (
name === "height"
? $(window).height()
: (name === "width" ? $(window).width() : name)
)
};
if (!$.isFunction(p)) {
// `$(window).width()` , `$(window).height()`
alert( a("width") + "\n" + a("height") );
}
jsfiddle http://jsfiddle.net/guest271314/2tuK4/
Why "show" method is not able to access "text" variable here ?
// #constructor A
var A = function(){
//alerts some text variable
this.show = function(){
alert("Hello")
alert(text);
}
}
//#constructor B
var B = function(){
//local text variable
var text = "World";
A.apply(this); // "show" method will get attached to B
}
var obj = new B();
//now calling show of B's object.
obj.show(); //returns error.
//Expected output
alerts "Hello"
alerts "World"
//Actual output
alerts "Hello"
ReferenceError: text is not defined
Am I missing something here ?
Shouldn't the "text" variable be accessible to B's "show" method?
Unlike C++ or Java, Javascript doesn't have an implicit this.
If a function (like show) refers to this.foo, then only the value of this depends on how the function was called.
However, if show refers to a variable directly (like foo), then it can mean either:
a local variable, if it's defined using var at the function scope;
a variable from a closure, if the function is being defined inside another function that happens to define it with var (closure gets created at the moment of function definition),
a global variable otherwise.
In your case, the third case applies. show can't access text because it is defined in a totally unrelated scope.
You need to declare the text as property of B constructor this.text = "World"; something like this.
var A = function(){
//alerts some text variable
this.show = function(){
alert("Hello")
alert(this.text);
}
}
//#constructor B
var B = function(){
//local text variable
this.text = "World";
A.apply(this); // "show" method will get attached to B
}
var obj = new B();
//now calling show of B's object.
obj.show(); //returns error.
I have a variable myVariable which is continuously changing. At some point I want to capture the value of myVariable (not a reference to myVariable) into another variable myVariableAtSomePoint.
Example code:
var myVariable = 1;
function test () {
var myVariableAtSomePoint= myVariable;
console.log(myVariableAtSomePoint);
}
myVariable = 2;
test(); // Prints 2, instead of 1.
You mention in your comments that myVariable is a number. Since myVariable houses a primitive type, simply use the code below:
myVariableAtSomePoint = myVariable;
Take a look at JAVASCRIPT: PASSING BY VALUE OR BY REFERENCE. Here's a quote:
When passing in a primitive type variable like a string or a number,
the value is passed in by value.
I would also suggest reading: How do I correctly clone a JavaScript object?
EDIT:
I believe that you're assuming that the placement of the function in the code affects the value of the variables. It does not. See examples below:
This:
function test () {
var myVariableAtSomePoint= myVariable;
console.log(myVariableAtSomePoint);
}
myVariable = 2;
test(); // Prints 2, instead of 1.
Is the same as this:
var myVariable = 1;
function test () {
var myVariableAtSomePoint= myVariable;
console.log(myVariableAtSomePoint);
}
myVariable = 2;
test(); // Prints 2, instead of 1.
Your problem is that you're changing the value of myVariable before you're assigning it to myVariableAtSomePoint. For this to work as you want, you'll need to call the test() function before you change the value of myVariable
var myVariable = 1;
function test () {
var myVariableAtSomePoint= myVariable;
console.log(myVariableAtSomePoint);
}
test(); // Prints 1
myVariable = 2;
test(); // Prints 2
IMPORTANT: No matter the placement of the function, the code inside test() is not executed until you call the function.
The variable only holds the reference and nothing else. If you want a copy of the object that the variable is pointing to, you will need some way to copy that object.
Either you can implement a copy method on the object itself (if you know what properties it has) or you can iterate through all properties on the object using a for ... in loop and copy them to a newly allocated object.
Something like:
//o is the object you want to copy
var o2 = {}; //gives a new object
for (x in o) {
o2[x] = o[x];
}
Your code:
var myVariable = 1;
function test () {
var myVariableAtSomePoint= myVariable;
console.log(myVariableAtSomePoint);
}
myVariable = 2;
test(); // Prints 2, instead of 1.
You assign 2 to myVariable, and then assign myVariable (which has now value of 2) to myVariableAtSomePoint via test() so of course it is 2. You don't need any magic copying here (since numbers are primitive) just assigment is enough.
You'll just need to copy each property on the object, of course if there are sub-objects they might get passed by reference as well:
function copy(o) { //could be called "clone"
var i, n;
n = {};
for (i in o)
{
if (o.hasOwnProperty(i)) {
n[i] = o[i];
}
}
return n;
}
You can do something this to do exactly what you wanted. It is slightly more involved however.
var myVariable = 1;
var test = null;
(function() {
const myVariableAtSomePoint = myVariable;
test = function() {
console.log(myVariableAtSomePoint);
}
})();
myVariable = 2;
test(); // Prints 1
First question
var obj = function(){
var a = 0;
this.b = 0;
}
Is there any difference in behaviour of a and b?
Second question
var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert('+x+')')
Is there any difference in behaviour of f1 and f2
Question 1
var obj = function() {
var a = 0;
this.b = 0;
}
Within the function, you'll be able to access both variables, but in the case of
var x = new obj();
... you'll be able to access x.b, but not x.a.
Question 2
As your question is written at the moment, it is a syntax error. The following will work:
var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert('+x+')')
... but that would be the same thing as writing:
var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert(a)')
The difference here is obvious. f1 disregards the global variable x and alerts whatever is passed to it, while f2 also disregards the global variable x, and tries to look for a global variable a. This is probably not what you're trying to ask about.
What you probably want is something like this:
var x = 'a';
var f1 = function(){ alert(x) }
var f2 = new Function('alert(x)')
... or this:
var f1 = function(x){ alert(x) }
var f2 = new Function('x', 'alert(x)')
The difference between the two alternatives above is that the first always uses the global variable x, while the second never uses any global variable. The difference between f1 and f2, internally, in both examples, is none at all.
These are two ways of generating the exact same result. The only reason you'd ever want to use the f2 approach would be when generating the code in some dynamic manner that require string input for its definition. In general, try to avoid this practice.
var obj = function() { // function expression, while obj is created before head
// it's only assigned the anonymous function at runtime
var a = 0; // variable local to the scope of this function
this.b = 0; // sets a property on 'this'
}
Now what this is depends on how you're calling the function.
Also note the difference between function statements and expressions.
var x = 'a'; // string a, woah!
var f1 = function(x){ alert(x) } // another anonymous function expression
// Does not work
// 1. it's "Function"
// 2. It gets evaluated in the global scope (since it uses eval)
// 3. It searches for 'a' in the global scope
var f2 = new function('alert('+x+')') // function constructor
In short, never use the Function constructor, it will never inherit local scope and therefore you can't use closures with it etc.
First question:
var obj = function() {
var a = 0;
this.b = 0;
}
instance = new obj();
instance.showA = function() {
alert("this.a = " + this.a);
}
instance.showB = function() {
alert("this.b = " + this.b);
}
instance.showA(); // output undefined - local scope only, not even to methods.
instance.showB(); // output 0 - accessible in method
Paste this in your Firebug console and run to see the output and behavior for yourself.
Second question:
var f2 = new function('alert('+x+')');
This throws a syntax error in Firebug because the f should be capitalized. This is a case where a function is defined inside a string and evaluated. Here is a good example:
var x = 'a=3';
var f2 = new Function('alert('+x+')');
f2(); // outputs 3 because the x passed into the variable is evaluated and becomes nested inside the quotes prior to the alert command being fired.
Here is what the substitution process looks like:
1: x = "a=3";
2: 'alert(' + x + ')');
3: 'alert(' + 'a=3' + ')'); // x replaced with a=3
4: 'alert(a=3)';
5: 'alert(3);'
When function runs, alert(3) is fired. This can be used to execute other JavaScript pulled down from a remote server, although extreme care should be used for security reasons. When evaluating code that is nested in quotes, it helps to start from the inside and work your way up to the top level context. More information on dealing with nested quotes or embedded code can be found here: http://blog.opensourceopportunities.com/2007/10/nested-nested-quotes.html
Question 1: homework on scoping of variables (var b is local to the enclosing {} (local to the function in this case).
Question 2: Instead of using the Function constructor you could use eval? http://www.w3schools.com/jsref/jsref_eval.asp , as in
eval 'alert('+x+')';
Second question is VERY interesting. Only benchmarks can say the truth.
http://jsperf.com/function-vs-function/
http://jsperf.com/function-vs-function/1..8
http://jsperf.com/function-vs-constructor-vs-eval
http://jsperf.com/function-vs-constructor-vs-eval/1..5
It looks they are almost equal? I can see in modern browsers each variant is optimized enough
BUT BE AWARE OF RECREATING THE FUNCTION IN A LOOP!
http://jsperf.com/function-vs-function/2
Any wise comments?