For the following code in Javavscript:
// add HTML to container
// show the container on the DOM
// call a non-existent function on an object
I successfully see Firefox and IE display my HTML. The third line of code, which shows a JS error in Firebug and IE, appears to be suppressed/ignored.
Do browsers generally ignore bad JS? Or, let's say I added alert("line 4"); after my 3rd line of code. Would the 4th line be ignored since JS interpretation would end on the illegal JS line of code?
I tested my scenario in jsFiddle, but I'm not sure if jsFiddle behaves in the same way as a browser.
The JavaScript engine will execute code until it reaches an Exception. The behaviour then changes depending on the following:
If it is in a try..catch, execution will resume from catch, otherwise
If it is invoked asynchronously this sequence will end at that point but other ongoing ones will continue. (A simple example is with window.setTimeout)
If it is directly in a <script>, the rest of the code in the <script> from that point will not execute, but code in following <script>s will.
If the Exception occurs in something that gets hoisted, then think of the point of execution as being on line 0.
You can test what happens easily using the throw keyword. For example
console.log(1); // logs
console.log(2); // logs
throw 'eep';
console.log(4); // does not log
Related
I want to modify the output of the functions (just say RANDOM examples, apologies for any code mistakes):
ng-if=!pfile.isgame
ng-if=! pfile.examplefile
-from false to true before it even has the page has any chance to drop any code on the page. How can I make it so I can append code to the page to the very beginning of the page to force every output of these particular functions to go true, on a live page?
This is definitely possible, I'm not sure where the function would be however the elements you can actually see the arguments on the page and it doesn't not look server sided at all, its just how its done. I read many articles but it many of them have not really helped me.
I am aware of Event Listener Breakpoints, its just the problem if I'm choosing the right one.
Thank you and I really appreciate it just if you can please dum down the explanation for me as even though I do understand HTML and JavaScript to an OK standard, I am still a massive beginner. This is something I always wanted to try out.
Hopefully I have understood your question correctly. There are a couple of options and the answer will depend on whether the functions are declarations or expressions.
If they are declarations, they get hoisted to the top on first pass, so that by the time your code begins execution, the function already exists and you can overwrite it early on.
If it's a function expression, you have to wait until the function expression has been created.
Example 1 (Function Declaration):
I have a function declaration on my page, which returns true if there is a remainder in the calculation, otherwise false. I execute it on page load. The output is false here:
function hasRemainder(first, second) {
return (first % second != 0);
}
console.log(hasRemainder(10, 5));
false
I have now added the Script First Statement breakpoint in DevTools, so that the debugger breaks before any script is run:
I re-open the page and the execution pauses. I now run the following code in the Console tab to override the hasRemainder function so that it always returns true:
hasRemainder = function() {
return true;
}
Finally, I click Play to continue execution. You can long click to select Long Resume, which skips breakpoints for 500ms so that you don't get caught for very single breakpoint thereafter.
true
The output this time is true as you would expect.
Example 2 (Function Expression):
We can't rely on the early breakpoint this time because the function won't exist yet. We need to add the breakpoint just after the function expression has been created.
Search for the functions using Cmd+Opt+F (Mac) or Ctrl+Shift+F (Windows).
When you are in the file with the function expression, put a breakpoint at the end of the function. When the debugger pauses, run the overriding function into the Console, and then press play to continue execution.
Basically call stack will start to pop out the function calls one by one when the last-in function call returns. But when ever I try to create a call stack nearer to the size of its maximum, An uncaught expression is getting raised.
//Code for testing the stack size
var cnt = 0;
function test(){
//Max stack size is nearer to ~41800
if(cnt++ == 41763){
console.log('finished');
return true;
}
return test();
}
test();
So the above code is throwing an exception for me in chromium Version 49.0.2623.112 m like below,
Uncaught exception
< true
Please not that the above error has no message in it. My question here is,
The last function call in the stack has returned true that means the stack size was not exceeded. why didn't the other function calls in that stack was not returned? And what is the reason for this blank exception message?
The problem here is
console.log('finished');
this adds some extra functions to the call stack that will let the limit exceed, but through exception handling your code gets executed anyway.
Try to run it without console.log and you see you get to the limit and see either a true or an exception.
The console.log is not in specification of javascript, so the behavior is undefined, and can be changed from release to release. So something that happens in your version maybe doesn't happen in ours.
Here is the most likely explanation for what happened: It is certain that console.log will increase the size of stack, and because is the last statement you call before the return, it can produce a Maximum call stack sometimes because you are very close to the limit. That Maximum call can be happen inside the console.log code(who calls something else), and how this error will handle it, it depends on the code of console.log. It seems like the code inside the console.log throws a Uncaught exception when an error happens. Now when you catch an error with try, code continues, that's why the true appears.
Here is an example in jsfiddle where I override the console.log and the results appear in the HTML. You can play by removing the override code of console.log to see how things change. Try this and tell us if the result seems strange again.
It's worth notice that when the Maximum call stack size exceedederror appears it depends on the size of the stack frame too (local variables).
Note: In ECMAScript 6 spec, if a function call is the last action in a function, it will not go in stack, but it will run "immediately", so your code will run without an error for all the numbers, no matter what number you put.
The Error in JavaScript internal/external file also stops the below code
For example:
var myObj = {};
myObj.other.getName = function(){
console.log('other is not defined');
};
alert('this will not show');
in above code, the alert will not come as the above code has error.
I added the same code in one file tst1.js and below this add one more file tst2.js. put alert('in tst2.js') in it. the tst2 alert come while tst1 not. it is some what related to
code compilation/interpretation.
It's much appreciated If someone explain me this behavior :)
This is the default behaviour of JavaScript. Avoid errors and the code will run normally.
Also you can handle errors with try...catch: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
All JS implementations are, AFAIK, single threaded. This means that all of your code is executed sequentially, on a single thread (logically). If this thread encounters a fatal error, it grinds to a halt. All code that comes after the point where the error occurs is ignored (the JS engine halted, no work is done anymore).
To clarify: it does not matter how many files you have. All of the JS code is stringed together into one big script, and this one script is executed sequentially (execution point starts at line 1 of the first script, and ends at the last line of the last script). Any errors in that code will cause the overall execution to grind to a halt:
//file1.js
var foo = (function()
{
console.log('This file is flawless, but pointless');
}());
//file2.js
foo();//calls previously defined function, assigned to var foo
//file3.js
fudhfsiufhi;//ERROR
//file4.js
foo();//will never get executed, because an error occurred in file3.js
Remove file3, or indeed fix the error, and everything will work as expected.
Allthough JS code is executed/evaluated sequentially, event handlers, callbacks, intervals, and timeouts might lead you to believe otherwise. Couple that with the fact that you have some control over what code is executed when, but not full control, and you get situations that, at first, seem rather counter intuitive. Consider this:
setTimeout(function()
{
massive(syntaxError) -123 + "here";
},0);//zero MS
alert('This will show');
This oddity is well documented, but it has to do with JS having a callback/handler loop, and queue. The setTimeout sets a timeout, to call the anonymous function in 0ms (immediately), but that callback is sent to the queue, which is checked periodically. Before the queue is checked (and the callback invoked), the alert will show. That's why the interval you pass to setTimeout or setInterval is not guaranteed to be exactly N milliseconds.
You can postpone a call to a method somewhat, by adding a call to the queue, like in the snippet above. But when the queue is processed, and what order the queued calls will be performed in are things you have no real say in. No say whatsoever.
It doesn't matter how many files, or how many statements that come before or after the problematic piece of code: there is no thread left to carry on.
The code you posted has a pretty clear error in it: you're assigning a property to other (a property of myObj, but this property is not defined anywhere, let alone defined as an object. Fix it by declaring properties first, before accessing them:
var myObj = {other: {}};//other is an empty object literal
myObj.other.getName = function()
{
console.log('This works');
};
alert('And the alert will show');
Your current code evalutes to:
var myObj = {};//object
var (myObj.other).getName = ...;
//evaluates to undefined
undefined.getName = ...//ERROR
undefined is a primitive value, actually signifying the absence of a value. undefined, therefore, cannot be accessed as an object, it can't be assigned properties.
Note:
This is just for completeness' sake, but JS is indeed single-threaded most of the time, but ECMAScript5 introduced Worker's which allow for some restricted form of multi-threading (without shared state, for example). Read through the MDN documentation on workers if you want to know more.
I have a lightweight logging function. To keep it simple its something like:
function log(msg){
console && console.log && console.log(msg);
}
which i have in a seperated file "Logging.js".
Now from another file lets say "hello.js" i do:
log("Hello");
Now if i make calls to that function the console will always display Logging.js:2 as the place where the logging occured. So there is no chance to determine from where the message originated. The log message should say hello.js:1.
Is it possible to find out from where the log function is called, find out the line number of the call and then manipulate the line number displayed by the console?
Or is there an easier solution?
Caution, please read carefully: Its NOT about the current line number. It's about the line number from where the function call occured and its about how to manipulate the log output so that it displays the line number FROM WHERE the function has been called. It's not about Errors or catching Errors.
I already postet this question some time ago and it was downvoted and declared as a duplicate of How can I determine the current line number in JavaScript? in no time, but it its not. This question is not about finding the current line number.
You can construct an Error object and look at the "stack" property:
$(function() {
function a() {
b();
}
function b() {
c();
}
function c() {
$('#e').html(new Error().stack.replace(/\n/g, '<br>'));
}
a();
});
JSBin
That'll show:
c#http://jsbin.com/aLuKUSU/1:33
b#http://jsbin.com/aLuKUSU/1:29
a#http://jsbin.com/aLuKUSU/1:25
#http://jsbin.com/aLuKUSU/1:36
b.Callbacks/c#http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js:3
b.Callbacks/p.fireWith#http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js:3
.ready#http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js:3
H#http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js:3
The "stack" property of Error objects is not standardized, but it's available in Firefox, Chrome, IE10+, and Safari 6. (Don't know about mobile browsers.)
I seem to be observing at least one case where a callback function passed to a jQuery effect function will execute repeatedly if there's an error while it's executing.
For example, see this JS Fiddle, featuring the following code:
$('#awesome').fadeOut(400,function () {
log('fading out...');
dieInAFire();
});
log appends whatever's passed to it to a div... but dieInAFire doesn't exist. Rather simply stopping execution, however, the anonymous function appears to be getting called over and over, as evidenced by the growing number of appearances of 'fading out...' in the log div.
Is this the expected behavior? If so, why?
It's a known bug. See the report here.
I just submitted a comment on the bug that patrick dw posted.
Changing the line:
options.complete.call(elem);
To:
setTimeout(function(){
options.complete.call(elem);
}, 0);
Causes the callback to execute asynchronously, and if it will no longer stop execution if it throws any errors. IMO it's better than using a try catch since it doesn't suppress the exception.
If you want to edit your minified version, and you use the latest jQuery, you can search for e.complete.call(d) and replace it with setTimeout(function(){e.complete.call(d)},0)