Sparround

Functions, scope and closures

Three main ways to write a function:

  • Declaration: function login(user) {...} — hoisted (callable before its definition)
  • Expression: const login = function(user) {...}
  • Arrow: const login = (user) => {...} — short syntax, no own this

Arrow functions are everywhere in test code: callbacks (items.map(i => i.name)), test blocks (test('...', async ({ page }) => {...})).

Default parameters are handy for test helpers: function createUser(role = 'customer') {...}.

Scope is where a variable is visible. let/const are block-scoped: a variable declared inside { } is invisible outside.

A closure is a function "remembering" variables from where it was created. Practical use: creating configured helpers.

In test code, closures underpin fixtures and factory functions — e.g. calling makeApiClient(baseUrl) returns a client that remembers baseUrl.

Prepare a short closure definition for interviews: "A closure is a function plus its lexical environment. The function keeps access to outer-scope variables even after that scope has finished."

📚 Sources and documentation