Bug 199823 - Object definition available before code execution on Safari - Function Hoisting difference between V8 and JavaScriptCore
Summary: Object definition available before code execution on Safari - Function Hoisti...
Status: RESOLVED DUPLICATE of bug 163209
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: Safari 12
Hardware: Mac All
: P2 Normal
Assignee: Nobody
URL: https://stackoverflow.com/questions/5...
Keywords: EasyFix, PlatformOnly
Depends on:
Blocks:
 
Reported: 2019-07-15 22:41 PDT by Paras Lehana
Modified: 2019-07-16 09:37 PDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Paras Lehana 2019-07-15 22:41:20 PDT
Objects and functions which I require only to execute once on a page load are wrapped inside an undefined check for the object. On Chrome on Windows/Linux which I usually use, the code works perfectly i.e. code only executes once. But on Safari on both iPad and MacBook, the undefined check doesn't work i.e. as per the browser, the object/function is already declared without even the code execution reaching there!

I've simplified my code to only include an if loop that checks if the nested function is already declared. Since it should not have been declared the first time, I've included someVariable inside the if that should never be undefined.

Run the same function on Chrome and Safari and see the difference.


if (typeof anObject == 'undefined') {

    function anObject(someParameter = 'someParameter') {
        var someProperty = 'someProperty';

        function someMethod(someParameter) {
            console.log(someParameter);
        }
    }

    console.log('Hi');
    var someVariable = 404;
}


On Chrome, you can see Console logging of 'Hi' as well someVariable as 404. But on Safari, there's no console logging and someVariable goes undefined.

If you put breakpoints to understand what's happening - the first undefined check never works actually. The anObject is defined even before the declaration.

I have tried searching about the differences regarding this between V8 (Chrome JS engine) and JavaScriptCore (Safari's engine) but haven't found anything solid. I assume this is something related to execution and function hoisting. It would be better if someone could explain to me the reason for this difference in execution. The behavior is the same on iPad that too even on Chrome!

Updates:

1. I've found a similar problem regarding different execution. Seems like this is something related to function hoisting but couldn't find any solid source yet. Javascript Hoisting in Chrome And Firefox

2. Looks like it is actually a hoisting behaviour now. This works by using function expression. In this case, simple replacing function anObject() with var anObject = function(). By doing this, I think, the variable doesn't get assigned the function reference even if the function is hoisted and evaluated before execution.

Chrome: 75.0.3770.100 Safari: Version 12.1.1 iPad Chrome: 75, iOS 12.3

Originally posted on StackOverflow here - https://stackoverflow.com/questions/57035056/javascript-object-definition-available-before-code-execution-on-safari

I was asked to raise this bug on Engine trackers.
Comment 1 Ross Kirsling 2019-07-16 09:37:49 PDT

*** This bug has been marked as a duplicate of bug 163209 ***