Home > Software design >  Function works only in Safari, other browsers throw `Uncaught TypeError: X is not a function`. Where
Function works only in Safari, other browsers throw `Uncaught TypeError: X is not a function`. Where

Time:11-16

I implemented a new feature to our CRM and everything works as it should on Safari (macOS), but it throws Uncaught TypeError: X is not a function on every other browser we tested it on (Chrome, Firefox, Edge). This is the piece of code that is the culprit:

if (window.changeLabel === 'undefined') {
  function changeLabel() {
    // Do something
  }
  changeLabel();
} else {
  changeLabel();
}

Why is it working only on Safari? Why is changeLabel not a function even after I check for its existence? Is this not the way to check if a function exists or not?

CodePudding user response:

That's not how you would usually register a polyfill. Normally, you'd do it like this:

if (window.changeLabel === 'undefined') {
  window.changeLabel = function() {
    // Do something
  }
}

changeLabel();

Note how we don't need the else block there.

CodePudding user response:

window.changeLabel === 'undefined' will return false regardless of browser because you are comparing a property value with the string 'undefined' and not the value undefined.

In Safari's sloppy mode the following will "leak" the function declaration outside of the block within which is was declared.

if(false) { function foo() {} }
console.log(foo) // function foo() {} in Safari, undefined in Chrome-based browsers

Chrome's sloppy mode behaves differently due to a different interpretation of the spec (the Web Compatibility Annex IIRC), meaning the function does not "leak", and remains undeclared.

[More details at the end

  • Related