0

I was experimenting around with scope inheritance within functions in Python and JavaScript and I want to fully understand why it runs how it does. Note: I have run the examples below in the lastest versions of node and python3.

Question 1: Why is the function expression in case B able to change the global function f() but case A is unable to?

Question 2: In python, we can implement case A as seen below. Is there a way to implement case B in Python and have it return 1?

JavaScript function definition (Case A):

function f() {
    return 0
}

function g() {
    console.log(f())
}

function h() {
    function f() {
        return 1
    }
    g()
}

h() // returns 0
console.log(f()) // returns 0

JavaScript function expression (Case B):

function f() {
    return 0
}

function g() {
    console.log(f())
}

function h() {
    f = function () {
        return 1
    };
    g()
}

h() // returns 1
console.log(f()) // returns 1

Python function definition (Case A):

def f():
    return 0


def g():
    print(f())


def h():
    def f():
        return 1
    g()

h() # return 0
ambiguousmouse
  • 1,835
  • 2
  • 21
  • 27

2 Answers2

2

When you omit var you create an implicit global; since the global f was already defined you override it, this should behave like case A:

function h() {
    var f = function () {
        return 1
    };
    g()
}

The difference between a function expression and function declaration is how the functions get hoisted but they are only visible in the function's scope, not globally. See here var functionName = function() {} vs function functionName() {}

Community
  • 1
  • 1
elclanrs
  • 85,039
  • 19
  • 126
  • 159
1

As elclanrs noted, the difference stems from the fact that in JavaScript, variables are global by default, while in Python, they are local by default. To answer the second part of your question, you can achieve the same effect in Python by explicitly marking f as global inside h:

def f():
    return 0


def g():
    print(f())


def h():
    global f
    def f():
        return 1
    g()

>>> h()
1

Why you would want to do this is a mystery.

BrenBarn
  • 210,788
  • 30
  • 364
  • 352