I'd love to live in a lint free world. JSLint that is. But I'm having some problems that I'm not sure I should ignore or fix. Specifically I'm getting a number of:
[functionName] not defined
errors. I do recognise that you should always define the function before using it and I assume that's what the message is really warning against but here are two cases where I think there is a valid exception:
jQuery(document).ready(function($) {
// code goes here
}
In a simple file which starts with a typical noconflict wrapper for jQuery I get a warning saying that "jQuery(document).ready(function($) {" is not defined. Obviously jQuery is defined in a separate file that needs to stay separate. Does that make sense?
The second example is really quite similar although arguably it is more avoidable. In this case I have two JS files in my project. One that looks just like the one above (aka, it's a set of DOM triggered events wrapped inside of jQuery's "ready" event). The other has a number of helper functions that look like this:
function doSomethingImportant() { };
function doSomethingImpressive() { };
These functions are then called within the first JS file. JSLint doesn't like this and complains every time the first JS file calls a function defined in the second JS file: doSomethingImportant() { is not defined. Yet in reality, since the functions are defined at load time and the calls to those functions always happen afterward based on DOM events there never seems to be a real problem.
Anyway, open to ideas. Is this a case of filtering JSLint's advice or something I should fix in code?
You're getting these errors because JSLint assumes that at some point in the future you might do:
var doSomethingImpressive = function() { }
in which case you would get an error, because the file where the function is defined is included after the function call (as explained here)
The same goes for the jQuery call. You can either change the order of your scripts, or safely ignore the errors.
Related
I am trying to write an app in Unity. I thought that the similarity between the JS and US allows to use JS libraries inside. Seems I am wrong, or I don't get somewhat. So the file is JSmol.min.moJQ.js (it can be downloaded here inside Jmol package, inside jsmol.zip or just the file itself here) and the piece of code which doesn't want to work properly is:
(function(a){
function j(a){
try{return a?new window.ActiveXObject("Microsoft.XMLHTTP"):new window.XMLHttpRequest}
That's not the full code, just first three lines. I've checked the brackets, these seem to be fine.
Now, Unity itself shows me that instead of j (function name) it expected a (.
I have tried to rename the function (just in case) -> Same error.
I have checked this page to learn about differences about US and
JS, but still it shows that the declared functions can be used, but
nothing about using them inside anonymous ones.
The bug page doesn't clarify the problem as well.
This page explains somewhat, at least I think I saw a usage of a declared function inside a declared other one. But again no clue for my case.
What do I miss? How can I fix this?
is there any option to set something like "breakpoint" on a file in chrome console (kindof shortcut to set breakpoint on every line of code in the file)?
Would be extremely useful when trying to understand 3rd party scripts that you know are executed but have no idea which part of code and from where is executed when.
My current example use case: I downloaded a script (form validation) which does not work as expected. The fastest way to solve the problem would be to pause execution anytime JS runtime enters this file and start exploring it from there.
I think this will be of use to you. I've recently been doing some work on the JavaScript Breakpoint Collection Chrome Extension created by Matt Zeunert, which allows you to inject breakpoints into your code at runtime - including breaking on property access/modifications, functions, scrolling events, etc. You can break on any arbitrary objects as well as the predefined ones using the console API.
Check out the project here.
If you can enumerate the functions publicly exposed by your third party script (for example if they are all properties of an object, or is their name has a pattern) you can make another script which dynamically replaces all those functions and force a break point :
thirdpartfunc = (function () {
var oldfunc = thirdpartfunc;
return function () {
debugger;
oldfunc.call(null, arguments);
}());
With the appropriate binding to this (if any applicable).
If you know the function(s) being called, you can use function breakpoints
debug(function);
function(...args);
When you call the function, it will hit the breakpoint. These aren't saved on page reload, but you can set a line breakpoint once you hit the function breakpoint.
This can get kinda tedious though.
If you have a array of functions, you can do
[function0, function1].map(debug)
#Tibos answer in another post would be good if there was some sort of babel transform to insert debugger; at the start of every function, instead of inserting it manually.
The quickest way for me was to do a global replace of the function declarations in the source, adding "debugger;" at the start.
In other words, replace
function [^{]*{
with
$0 debugger;
Your regexp may vary depending on the escapes you need. For example:
function [^{]*\{
You may also need more than one pattern to handle all the function declarations you have.
This has nothing to do with the Chrome console though.
No. You would have to add breakpoints to the various function entry points that file contains to catch everywhere it could enter.
Can't you just place a breakpoint at the first line of every function in the file of interest?
We had a situation today where 1 small error (on line 500) in our JS library file (3000+ lines long) caused a runtime error (calling a method on an undefined object).
The error stoped further execution of all other code in the library file causing our site to not work properly.
My question is:
Since JS is single threaded, will splitting up our code into multiple files and scopes help resolve issues like that in the future?
If we don't split it up, how can we prevent this from happening.
thx,
You can't : js scripts are loaded at once.
The only way to prevent it is to design your code correctly, using try/catch and to write and run tests
Simple solution would be to check if the object exists before attempting to call the method on it.
if ( myObject && myObject.myObjectFunction )
myObject.myFunction();
else
return false;
If the object exists and the object has the function you want to call then it'll call the function, otherwise it'll return false and not attempt to call the function, thus avoiding the error entirely.
I've written a server-side utility that is meant to manage javascript page dependencies. During development, it serves the javascript as separate files (embeds individual script tags in the order defined), and in production mode it reads the files, minifies them (Google Closure in Whitespace only mode), and embeds them via a single script tag.
For the moment, I've turned off minification to eliminate that variable...so all it is doing is joining the files together with a newline between each.
When I go to production mode, I get spurious problems in a number of the files that are embedded.
So, does anyone have any ideas of what problems I could be causing by serving a set of files as a single, concatenated file? I'm at a loss.
For those wanting more detail:
I am certain the order is correct.
The list of files in question is rather large for this example, but include jquery, angular, controllers, jquery dnd fileupload, controllers, etc.
I get "Uncaught Type Error: undefined is not a function" at this line of the combo:
(function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return;}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return;}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f);}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return;}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown");};c._touchMove=function(f){if(!a){return;}this._touchMoved=true;d(f,"mousemove");};c._touchEnd=function(f){if(!a){return;}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click");}a=false;};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f);};})(jQuery);
which follows some other file embeds that generate global vars:
var FocusElementDirective = function() {
...
}
var DirectiveApplier = function(){
...
}
var AgeCalculator = function(){
...
}
Another one: when I trigger an "add" event in the angular plugin for jquery fileupload, it gives Uncaught TypeError: Object # has no method 'scope'. The line it is pointing to is within the jquery fileupload angular module (line 89 of version 9.0.5):
add: function (e, data) {
if (e.isDefaultPrevented()) {
return false;
}
var scope = data.scope(), // this line
Just happening upon this and the first thing that comes to mind is that it could be something to do with global variables, one of those things Crockford complains about as a weakness of javascript.
For a quick description:
JavaScript global variables & self-invoking anonymous functions
Just off the top of my head.
So, I found it, and it turned out to be something ultra-simple...so simple that I pulled my hair out for hours looking for something technical:
I had a duplicate.
When loaded as tags, the browser only bothered to load the file once. When concatenated, the code was actually duplicated. This led to all sorts of weirdness (e.g. event handlers were getting hooked to the wrong version of things).
Coming from a compiled language background, I kinda would expect some duplicate symbol kinds of notifications...ah dynamic languages.
After using functionality from this question for debugging I am wondering is there a way to get the file name from which the function was invoked and may be the line.
May be I am asking for too much, but I know that in some of the languages it is possible.
If this is not possible can anyone mention why his functionality was not implemented?
I will try to rephrase the question, because I think I didn't make myself clear.
I have file.js in which on the 17-th line there is a declaration of the function:
...
function main()
{
Hello();
}
I have another file test.js, where I define function hello
function Hello()
{
...
which tells me the name of the file and a line in which the function which evoked it was defined
}
So for example if I will call
main(), it will tell me file.js, 17 line
It has nothing to do with firebug
If all your doing is debugging, hy not just use the debugger built into modern browsers?
debugger
That line is all you need. You can examine the callstack, inspect variable values, and even run code in the current scope.
Such functionality makes your request kind of unnecessary.
You don't mention what browser you are using.
In Chrome what I would suggest is inserting a breakpoint on the first line of the function. Then reload the page (or otherwise trigger the function call). When execution pauses at the breakpoint, check the Call Stack section in Chrome's Developer tools - it will give you a stack back-trace of the flow of execution.
I'm sure Firebug offers something similar if not identical, it's just been a while since I used it.
Cheers