Scope of javascript variable declared inline - javascript

Here are the problem scripts:
This is from the HTML file:
<script type="text/javascript">
var devices_record = "some string";
</script>
<script type="text/javascript" src="/js/foo.js"></script>
This is from foo.js:
function bar () {
devices_record = "assign new string";
}
The error report by HttpFox is that devices_ record is not defined. What gives? I thought devices_ record will be a globally scoped variable so it should be accessible from anywhere.

Your test case works for me. Here is my complete test:
foo.js:
function bar () {
alert(devices_record);
devices_record = "assign new string";
alert(devices_record);
}
foo.html:
<html>
<head>
<script type="text/javascript">
var devices_record = "some string";
</script>
<script type="text/javascript" src="foo.js"></script>
</head>
<body onload="bar()">
</body>
I get two alerts, the first says "some string", the second "assign new string".
Your problem exists elsewhere in your code.

I believe your given code works. At least executing the code you give above will not cause any errors.
Also, it's better to include your dependencies such as foo.js before using any inline js. This ensures your library is loaded before calling functions provided your library.
Also, assignment operators will not cause 'devices_ record is not defined' errors because you ARE defining it with the assignment operator.
Your error is probably caused by something else.

Declare devices_record in foo.js. Then, reference it from the javascript embedded in the HTML.
You may also consider wrapping your foo.js code in a class, with devices_record as a field/property. This can make for much easier error trapping, among other things.
Tidbit: also, if devices_record declaration were placed before the script inclusion, the script may be able to access it. However, be wary of declaring variables outside of the file that uses them. If you decided to include that script in a page that forgets to declare devices_record, you'll run into errors.

Related

Avoiding global scope?

I like to include my javascript in each page that needs it (more general js files go in the document head):
-- item.html --
<div id="item">
<script type="text/javascript" src="item.js"></script>
...
</div>
so in my script file I can now grab the container and use it to find things:
-- item.js --
var container = $('scripts').last().parent();
var f = container.find('form');
however, if the work needs to be done after the page loads:
$().ready(function() {
var f = container.find('form');
});
I have a problem because container scopes across files. consider:
-- index.html --
<div id="item">
<script type="text/javascript" src="item.js"></script>
...
</div>
<div id="link">
<script type="text/javascript" src="link.js"></script>
...
</div>
<div id="part">
<script type="text/javascript" src="part.js"></script>
...
</div>
where the item.js fails because it picks up the last value container was assigned, instead of the one it was assigned at the time that it was declared such that it in essence performs:
$('#part').find('form');
instead of what I want:
$('#item').find('form');
so my question: how do I make the scope of container local to the file where it's declared?
alternatively, how could I do this differently?
Please look into modularizing your code using something like AMD to solve this. This is exactly what AMD was designed to solve.
There are several possible libraries for this. Since you are using jQuery, RequireJS might make the most sense, however there are other solutions as well, such as
CommonJS using Browserify
Webpack
Duo
RequireJS
I don't a environment to test this on, but would this small alteration work?
var container = $('script[src="item.js"]').parent();
You would have to specify the filename for each scope, but that doesn't seem like much of a burden.
JavaScript in the browser is functional scope. Which means variables declared (using the var keyword) belongs to the top most function, or the global scope if there is no function.
So to answer your question, in every file, you can do:
(function() {
var someVariable = 1;
//...
})();
What this does, is first evaluates and creates the anonymous function, and then immediately executes it with no arguments.
Since you are executing a function, any variables that you declare (as long as you use var), will be scoped to the function, and won't be available globally.

Javascript global variable when using Scripts.Render MVC4

I have an MVC 4 project that utilizes javascript bundling.
In my _Layout.cshtml page I have something like this:
#Scripts.Render("~/bundles/scripts/desktop/modernizr",
"~/bundles/scripts/desktop/jquery","~/bundles/scripts/desktop/jqueryui",
"~/bundles/scripts/desktop/jqueryvalidation", "~/bundles/scripts/custom")
There are others, but this is just an example. Within one of my scripts that's called in the custom script I need to reference a global variable that set within the ready function, as shown below:
<script type="text/javascript">
$(function () {
//alert('Page is ready!');
var warning = 10;
var timeout = 20; }); </script>
Problem is, I always seem to get an error within the method that requires the warning and timeout variables. Am I missing something obvious (not to me, though!) on how I should create these variables? Should I var them outside the $Ready, because the js is loading before the page is technically ready?
Where should the global variable go, if everything is already in a render bundle and there are no script blocks?
Thanks!
The warning and timeout variables aren't global. They've only been defined within the function that you provide to the $ function.
I'd generally recommend avoiding global variables where possible, but if you really want to create global variables just use this:
<script type="text/javascript">
var warning = 10;
var timeout = 20;
</script>
Or this:
<script type="text/javascript">
$(function () {
window.warning = 10;
window.timeout = 20;
});
</script>
Thanks for the response.
I don't think adding the variables in the Ready page will work. The functions that require these variables are loaded before the page is 'ready' (per my understanding how this all works), so there are situations on a new page load where the variable will be required but unreferenced.
This is how I'm currently handling it:
I created a new .js file, with the following:
var warning;
var timeout;
Then I created a bundle reference to the file and put it into my #Script.Render stmt in the correct order for scope. Now, I have my global variables, and it's cleanly implemented into my view code. Now, I know that I should be passing around variables vs. having them global, but in this case I don't see a major issue.

What is the global scope of <script> tag?

I had made flag and made my previous question deleted because of missunderstanding.
I'm working on a classic asp project.
let's say you have so many <script></script> tags in your code.
For instance:
line 10: <script> ..function 1 definition here..</script>
line 200: <script> .. function 2 definition here..</script>
line 5000: <script> ..function 3 definition here..</script>
also at line 6000: I have another tag which is trying to call function1.
is that possible without using *.js file ?
For instance:
line 6000:
<script> function1(); </script>
Those scripts are not defined in <head> tag.
I know its not useful but I need to know is there any way of it or not.
Hope its more clear now!
anything inside the script tags gets run immediately. if you define function a() in your first script element, then it will add a function called a to your global namespace. any javascript you execute later on in other script elements will have access to it.
<script type="text/javascript">
function a() {
alert('hi');
}
</script>
...
<script type="text/javascript">
a();
</script>
Yes, that is possible, assuming function1 is in the global scope (e.g. not in a wrapper function/self-invoking function).
Of course it is possible . You just need to define it in global namespace. Here is the link which should give you an idea and better understanding. It also includes very simple examples.

Uncaught ReferenceError: X is not defined - declaring object on js file, making reference inside html button event

I want to define a Javascript object inside a js file and make it possible for users to create new instances of it on their HTML by calling the src on the head and then using "new". [maybe this is not the best approach, but bear with me] -- very basic stuff, right?
Code in JS file myFile.js:
function myObject(){
this.myMethod = thisMethod;
function thisMethod(){
return 2;
}
}
Code in HTML:
<head>
<script type="text/javascript" src="http://myserver/myFile.js">
var customObject = new myObject();
</script>
</head>
<body>
<input type="button" value="Click Me" onclick="alert(customObject.myMethod());">
</body>
However, when you click the button, you get an error:
"Uncaught ReferenceError: customObject is not defined"
I am sure this is about how I am declaring the instance and then calling it. If I put the var declaration inside the js file, the click works:
function myObject(){
this.myMethod = thisMethod;
function thisMethod(){
return 2;
}
}
var customObject = new myObject();
But this defeats the purpose of letting the user create the object and use it at will.
Of course there is a problem with my structure, but all my researches don't give me a clue. I thought bringing the js file was the same as putting the code inside script tag in the HEAD and instantiating the object there -- because if I do that, without .js call, it works.
I have many theories, some of them regarding events and the order where things are loaded, but don't want to clutter this question.
So the question is: how to you define an object in a js file, then let the user instantiate and call its methods inside the HTML? (Especially for events like onclick)
The problem is that you can't use the same tag to both include an external resource and define your javascript code. You have to use 2 separate tags, otherwise whatever code you put inside the tags will be omitted. This works fine:
<script type="text/javascript" src="http://myserver/myFile.js"></script>
<script type="text/javascript">
var customObject = new myObject();
</script>
Hope it helps,

Functions with same names in JavaScript

I tried to write a function on a JS file and another function with the same name in the page.
I expected an error but no error came and I got only the function from the JS file to execute.
How is this possible? Even if I write a function in a separate JS file, everything is rendered in a single html file. Then how come it is possible?
<script type="text/javascript" language="javascript" src="JScript.js"></script>
<script language="javascript">
function Boo() {
alert("Hai new");
}
</script>
<button onclick="Boo();">Click</button>
and in the JS file
function Boo() {
alert("Hai");
}
One aspect that not many people ever think about with JavaScript is
that if you define multiple functions
with the same name then the last one
defined will be the one that actually
runs. JavaScript functions are not
polymorphic the way that functions in
many other languages are in that
JavaScript doesn't care if the actual
arguments defined for the functions
are different as it can't distinguish
between them on that basis. Where in
other languages you might have
myfunc(oneparm) and myfunc(parmone,
parmtwo) as two separate functions
with the one that gets run depending
on the number of parameters passed, in
JavaScript the last one defined will
always be the one run regardless of
the number of parameters.
http://javascript.about.com/library/blpolyfunc.htm
Named functions in javascript are more like variables. If you change the value of a variable, no error occurs, the variable simply has a new value. The same can be said of a function in javascript.
In JS you can redefine functions. A subsequent function with the same name as another function will overwrite it. (Subject to scope)
Because it gets overwritten by the latest one.
JavaScript is highly forgiving in these aspects (like redeclaring a variable or function). The latest one hides or override the previous ones.
In your case, I assume that the js file was loaded after the function Boo inside the html was parsed. Thus when you click on the button, the definition of Boo in js file is the only Boo available.
Case 1: Internal JS has higher priority than External JS, that s why the function written in internal JS override/replaces the other function(with same name) written in external JS file. Example Below:
Internal JS file:
<script type="text/javascript" language="javascript" src="JScript.js"></script>
<script language="javascript">
function Boo()
{
alert("Hai Internal");//this function will simply override the one
//written in external JS file
}
</script>
<button onclick="Boo();">Click</button>
External JS file: JScript.js
function Boo()
{
alert("Hai External");
}
Case 2: If two function with same name exits in the same file,
the one that is declared last(close to the bottom of the file) will override the function above of it. Example below:
<script language="javascript">
function test() {
alert("test 1");
}
function test() { // this will override/replaces the above function
alert("test 2");
}
</script>

Categories