Is there any reason why the following would not work:
for (i=0;i < someArray.length;i++) {
if (someArray[i].indexOf("something") !== -1) {
//do something here
}
}
The most basic "for" loop possible. But it doesn't work. On the first line (declaration of the loop, not inside the loop), I get "Uncaught reference error; i is not defined."
I have this page open in one Chrome tab, and another earlier version of the page open in another tab. In the other tab, this loop works just fine; in the first tab, this code throws an error.
EDIT - July 2 2015
The response about strict mode was helpful. After reading up a bit and going through the code I've got a handle on what's going on.
The confusing bit was that both versions of the code look like this, with some minor differences (requirejs module):
define(
'viewModels/someViewModel',
['dependency1', 'dependency2', 'dependency3'],
function(dep1, dep2, dep3) {
"use strict";
function SomeViewModel(arg1, arg2) {
var self = this;
self.initialize();
self.removeRefinement = function(refinementString) {
var refinementArray = refinementString.split("&");
for (i=0;i < navigationArray.length;i++) { //<-- error
}
}
}
}
);
One version throws the reference error. One doesn't.
This is a large web application with many other pages and Javascript files. The only thing I could think of was that in one version of the code, maybe i had been inadvertently globally defined somewhere else in the app, where strict mode wasn't enabled. After running to the breakpoint and checking "window" I see that's exactly what's happening.
Thanks =D
If you are in strict mode, you'll get the error Uncaught reference error; i is not defined. If you're not in strict mode, you won't get the error.
This will throw the error
'use strict'
var someArray = ['aaa', 'bbb', 'ccc'];
for (i=0;i < someArray.length;i++) {
console.log(i)
if (someArray[i].indexOf("something") !== -1) {
//do something here
}
}
This won't
var someArray = ['aaa', 'bbb', 'ccc'];
for (i=0;i < someArray.length;i++) {
console.log(i)
if (someArray[i].indexOf("something") !== -1) {
//do something here
}
}
when you declare a variable it must be declared like this var i = 0;
a for loop looks like this:
JavaScript
for(var i = 0; i == 10; i++)
{
}
Related
In my project, I make a require call to a js file to create an object of the file.
For example,
require(['directory/hello-js-file'], function(Hello){
var hello = new Hello();
hello.show();
});
After this block, Hello is undefined. In the IE console, I see this error message, 'SCRIPT1003: Expected ':' File: Function code (13), Line:2, Column:1'
The function looks like this:
function anonymous(){
return eval(arguments[0]);
}
I was able to narrow down this issue being originated from two functions (Contents have been modified but the logic is same.):
bindDetail: function($view){
var self = this;
var details = object.details; // object is a global variable
for(var i = 0; i < details.length; i++){
if(self.hasData(details[i])){
// doSomething
}
}
},
hasData(detail){
if(detail.data !== undefined && detail.data !== ""){
return true;
}
return false;
}
This issue only arises in IE. This works fine in Chrome.
Can someone please direct me to a solution? Thank you. I appreciate your help.
After posting the question, I realized that I was missing the :function tag to hasData. That resolved the issue. :)
This bit of code:
function get() {
console.log('get')
}
var obj = {
get
}
obj.get()
results in a SyntaxError: Unexpected token } in iojs and Chrom{ium,e} but works fine in Firefox.
Longhand, of course, works fine:
function get() {
console.log('get')
}
var obj = {
get: get
}
obj.get()
So does using a word other than get
function git() {
console.log('get')
}
var obj = {
git
}
obj.git()
Is this a bug in V8 or something else? What am I not getting here?
v8 hasn't made this available by default yet1; firefox (which doesn't use v8) has.
For now, you can transpile with babel.js.
1 It's available, but not in every runtime environment. In node.js, for example, you need to enable it with a --harmony_something flag.
I have a code to extend the htmloptionscollection object:
HTMLOptionsCollection.prototype.contains = HTMLOptionsCollection.prototype.contains ||
function(otherOption) {
for (var i = 0; i < this.length; i++) {
if (this[i].value === otherOption.value) {
return true;
}
}
return false;
};
It works well on firefoxa dn in Opera but does not work in IE9 and in Google Chrome it shows:
"Uncaught ReferenceError: HTMLOptionsCollection is not defined"
How can I solve this problem. Am I doing anything wrong? If I am, how can I solve it?
If you do something wrong then the wrong thing is that you assume that the whole DOM is supported by any browser. For example IE: I don't see any prototype for HTMLOptionsCollection on MSDN
this is my first post, but i'm excited to join this community. I have a question regarding JavaScript which I am completely stumped about.
I'm writing a JavaScript application which pulls data from a server using ajax and adds it to a chart. I'm using Jquery and Highcharts as the framework and then writing my own JavaScript 'wrapper' around Highcharts to produce the interface.
When the processData function get called back with the jSON response, it begins with i=1, even though i shouldn't even be initialized or even declared yet. Other variables are set as well. (I know this from using chrome developer tools to debug). This makes my loop not execute and none of my data gets added to the chart.
I don't know how much code to show, but these are the most relevant parts. I can add more if needed.
function getData(series, min, max, numpts) {
if (series === undefined) {
console.log("error on getData");
return;
}
var request = {};
request.series = series;
if (min !== undefined) {
request.start = min;
} //in seconds
if (max !== undefined) {
request.end = max;
}
if (numpts !== undefined) {
request.numpts = numpts;
}
$.getJSON('/data', request, processData);
return;
}
function processData(data) {
// handle the data after it comes back from an ajax request
var curSeries,
chartSeries,
curPoint;
for (var i = 0; i < data.length; i ++) {
curSeries = data[i];
chartSeries = chart.get(curSeries.name);
if (chartSeries === null) {
//alert("oops");
chart.addSeries(curSeries);
} else {
for (var j = 0; j < curSeries.data.length; j ++) {
curPoint = curSeries.data[j];
chartSeries.addPoint(curPoint, false);
}
}
}
chart.redraw();
}
These are both methods of a class I declared called graph.
Thanks if anyone has any ideas!
-Matt P
I'd console inspect your data object to make sure it's what you expect, as that loop should be working fine even if i is pre-declared: you're assigning 0 to it at the beginning of the loop, anyway.
The only reason I can think of that i would be defined and initialized before you defined and initialized it is if somewhere else in your codebase you don't initialize the i with the var keyword. Doing that would dump it into the global scope (the window object), making it available via closure to any and every function in your codebase.
If it's not in one of your files, it may be in the highcharts graphing library (in which case run very quickly away from said library).
In any programming language, I can trace any function and know which function is called by other. But in Javascript , I don't know how, since the code is not written by me and Firebug does not give this feature - as far as I know.
An example :
I want to display the function names of each function that is called when clicking on XYZ Element, and display them in order.
Found this: A javascript stacktrace in any browser, James says they have a github account now
function printStackTrace() {
var callstack = [];
var isCallstackPopulated = false;
try {
i.dont.exist+=0; //doesn't exist- that's the point
} catch(e) {
if (e.stack) { //Firefox
var lines = e.stack.split('\n');
for (var i=0, len=lines.length; i<len; i++) {
if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
callstack.push(lines[i]);
}
}
//Remove call to printStackTrace()
callstack.shift();
isCallstackPopulated = true;
}
else if (window.opera && e.message) { //Opera
var lines = e.message.split('\n');
for (var i=0, len=lines.length; i<len; i++) {
if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
var entry = lines[i];
//Append next line also since it has the file info
if (lines[i+1]) {
entry += " at " + lines[i+1];
i++;
}
callstack.push(entry);
}
}
//Remove call to printStackTrace()
callstack.shift();
isCallstackPopulated = true;
}
}
if (!isCallstackPopulated) { //IE and Safari
var currentFunction = arguments.callee.caller;
while (currentFunction) {
var fn = currentFunction.toString();
var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf('')) || 'anonymous';
callstack.push(fname);
currentFunction = currentFunction.caller;
}
}
output(callstack);
}
function output(arr) {
// Output however you want
alert(arr.join('\n\n'));
}
You can see the stack trace of any error with the stack() function call (on Firefox). Creating a simple function to print a stack trace could look like this:
function getStackTrace() {
try {
unusedVariable++; // This creates an error we can trace
}
catch (e) {
return e.stack;
}
}
Other browsers have different ways of printing the stack trace, but this should get you what you need for Firefox.
Hope this helps.
DynaTrace AJAX has some of the features like that. Not exactly what you are looking for but gives you the events and functions bound on an element and helps your troubleshooting. Had a free download, check it.
If you simply want to debug your code, your best option is to get a debugger plug-in for your browser. The Firebug plug-in does provide stack traces. (see here)
If you want to do it from within your code, there is no standard language feature of JavaScript that allows you to do this. Different browsers may implement non-standard extensions, but you shouldn't rely on them.
As "Casablanca" mentions... please note from the site of the aforementioned js-stack-trace (
http://www.eriwen.com/javascript/js-stack-trace/ ) that in FireFox and Chrome:
Obvious easy way: Firebug, Chrome Dev Tools, Dragonfly etc.
You can easily get a stack trace at any time by calling
console.trace() in your Javascript or in the Firebug console.
Since it sounds like you want to inspect the stack and take pieces of the information (the function names), sounds like you need
stackinfo
which was built exactly for that purpose.