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