How do I prevent IE from breaking when passing Console to IIFE - javascript

I have a script which needs to work in IE browsers < v11. Don't ask me why! It seems the console object is not available when IE does not have developer tools running and this causes problems.
I can't find a way of preventing the script from failing other than writing messy checks for undefined.
Here is some sample code using an IIFE:
var vm = (function ($, c, opts) {
}(jQuery, console, window.MyAppSettings));
I can't even test for undefined inside the IIFE as this seems to break before it is called. Is there any convention for this sort of thing?

Related

The cause for TypeError: access to strict mode caller function censoered

I'm working on a web application that uses the JMol Javascript extension with Angular. This is challenging. It's been working quite well, but today it stopped working on Firefox. When I try something JMol complains with the error
TypeError: access to strict mode caller function censored
This is happening in 3rd party code, only on Firefox (which has updated itself yesterday). It works well on Chrome.
I found some people complaining about a similar error over the years (without using JMol). They all received interesting answers - downgrading jQuery to 1.1, wrapping some function call in setTimeout and other such answers.
I could not find an explanation for the cause of this error. What is a strict mode caller, which access is censored, and why? I would also love to see a minimal piece of code that generates this error on Firefox - so I can understand what I'm trying to fix.
What's happening is that code that tries to use the caller property of a function is being called by strict-mode code. Example:
function attemptToUseCaller() {
console.log(attemptToUseCaller.caller.name);
}
function loose() {
attemptToUseCaller();
}
function strict() {
"use strict";
attemptToUseCaller();
}
loose();
strict();
If you run that in an up-to-date version of Firefox, you'll see this in the console:
loose
TypeError: access to strict mode caller function is censored
As you can see, accessing attemptToUseCaller.caller worked when the calling function was in loose mode, but failed when the calling function was in strict mode. Accessing the caller property is disallowed in strict mode, and even disallowed when used in "loose" code, if the caller function is itself strict. Firefox raises a specific error, whereas with Chrome's V8 JavaScript engine, it just returns the value null for .caller in strict mode.
Using caller is an anti-pattern. You'll need to fork whatever 3rd-party code is using it and correct it.

should I use a js function other than console.log(message)?

I would like to use console.log(message) to write out some information to the browser console. However, I came across this url which seems to recommend against it:
https://developer.mozilla.org/en-US/docs/Web/API/Console/log
Are you currently choosing to use console.log(message) as part of your js code? If not then have you identified an alternative?
I agree with Mike C above-- console is generally available in most browsers, but you should probably remove console logs before a site gets pushed to production.
Additionally, some older browser might not have the console, and if you did accidentally leave in a console log, it would fire an error when it attempted to interact with with something that wasn't defined. As an extra failsafe, you can declare console and console.log in the global namespace if they are not detected, just in case:
if (!console) {
console = {
log: function () { //noop }
};
}
should I use a js function other than console.log(message)?
simple answer is yes, But also the console.log(message) is usaually used for testing purposes and for other relevant intentions like letting other developers interract with your js source code in some sort.
However.
You should not use it to log very important messages as this could be a hole your application presumably.
Hope it helps.
While the console object is not defined in the official Javascript standard, it is specified in:
Google Chrome
Mozilla Firefox
Internet Explorer 9+
Opera
Safari
Node.js
PhantomJS (since it uses V8 like Chrome and Node.js)
and more, I'm sure. As long as you're debugging in any of the environments which supports it, you're fine. You should be removing your logging statements before pushing to production anyway so as long as it works for debugging, it's nothing to worry about.

How do I load certain scripts for certain browsers?

I have an app up and running, and it works great in Chrome and Firefox. Safari is another story. For the sake of example, let's pretend this is my app:
'use strict';
const x = 3;
function test(){
let y = 4;
return y;
};
When I run it in Safari I get:
SyntaxError: Unexpected keyword 'const'. Const declarations are not supported in strict mode.
Then if I remove 'use strict' I get:
SyntaxError: Unexpected identifier 'y'
At this point I decided to take my first look into transpiling, so I installed Babel and I have my client-side code converted to ES5 and sitting in a new folder.
My question now is, what's the best practice for loading the original code if a user is using Chrome/Firefox, but loading the transpiled code if they're using Safari? Is my head even in the right place here?
To detect if safari is being used:
var safariCheck=Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
Then you can load the code you want for safari if the above statement qualifies.
If it does not you can load the Firefox or Chrome code.
The cleanest way to check feature is to use Modernizer
With this library you can check that browser have es6 feature ready with this code:
if (Modernizr.es6array) {
loadNewCode();
} else {
loadOldCode();
}
You can find more examples and documentation here.

What is going on with this javascript bug involving the word "event" in Firefox?

I am using the Lungo framework. I am trying to understand if there is a bug in my code or a bug in the framework because I want to "blame my code before blaming others." This line of code is throwing the following error in Firefox 26.0 -- but not in Chrome 31.0.1650.63:
_sameSection = function () {
var dispacher_section, same;
if (!event || !lng.Element.Cache.section) { //event is not defined
return true;
}
I know that event is not a reserved word in javascript (Is 'event' a reserved word in JavaScript?) -- but it is a global variable in IE. Is it also a reserved word on Chrome? Because I don't get this error on Chrome.
If I look back through the code, I see that event is not defined as a variable outside of the scope of this function. So it seems like it has to do with how different browsers handle the "event" word.
Consider using explicit check instead of implicit:
typeof(window.event) === "undefined"
Different browsers have different behavior about special cases of other browsers (which is why libraries like jQuery is easier - many of the one-off cases are handled inside library already).

on a javascript error, how to identify method or js file with the problem?

When a javascript error occures in IE (or in other browsers) you get a popup saying that javascript error has occurred - usually this comes with a line number and some hint.
Sometimes it comes with line 0 and with no way of knowing what the problem is.
Javscript can come from HTML itself, from a js file or from JSP (and more).
Microsoft has a script debugger that helps a lot in finding where js errors are, however sometimes when a js error occurs the script debugger cannot find the code portion and thus its difficult of finding where is the root cause of the problem.
My question is whether anyone knows any way of making script debugger find the code any way (mostly happen with js code that is in JSP file), or at least include in the IE popup the method or js file where the error has occurred. (it only display the line number, and many times its line 0...).
Thanks,
Tal.
The error object which is created when an error is thrown by JavaScript is very unreliable when it comes to the source line, especially within IE. Browsers like Firefox and Safari are better at line numbers, but they are generally pointless due to minification of the files.
What is obviously of more use is getting the call stack, but due to the anonymous nature of JavaScript functions (well, that they can be anonymous) a call stack can often be hard to work out.
If you're doing a try/ catch you can do arguments.callee which will return you the method which called the current method which failed.
Here's a good example of doing a complete stack in JavaScript - http://eriwen.com/javascript/js-stack-trace/
Also developer tools included with Internet Explorer 8 is something good to trace and debug your javascript code
There is a version of Firebug called Firebug Lite that will work with Internet Explorer. It's performance is going to be based on how complex your pages are; however, for relatively lightweight pages, it should provide some insight.
I recommend this tool rather than simply using Firebug and Firefox because not all errors that occur in Internet Explorer will occur in Firefox, and so performing any debugging in that browser may not yield any results.
Firebug on Firefox is usually considered one of the best debugging tools.
On Firefox, go to
http://getfirebug.com
to get it.
This will print you a stack trace:
function Stack()
{
try
{
throw Error()
}
catch(ex)
{
return ex.stack
}
};
print( Stack() );
If all else fails (and when dealing with IE it sometimes does) you can always walk through your code with alerts. It's crude and tedious, but sometimes it's all you can do:
Simply:
var count = 0;
then sprinkle some:
alert(count++);
at strategic lines along your code and note where it stops alerting.
Lather rinse repeat until you have your line.
If using Firefox you can press Ctrl + Shift + J to bring up the JavaScript error console that is built into Firefox, which will tell you exactly what went wrong.

Categories