Skip to main content

Command Palette

Search for a command to run...

Lesson 52: Mastering JavaScript "new Function" syntax with challenges!

Published
β€’6 min readβ€’View as Markdown

What is new Function?
It’s a way to dynamically create a new function from strings at runtime.

🟩 Syntax:

let func = new Function([arg1, arg2, ...argN], functionBody);
  • Each argument and the body are passed as strings.

  • Returns a new function.

let sum = new Function('a', 'b', 'return a + b');
console.log(sum(2, 3)); // 5

🧠 Key Insight:

Unlike normal functions, a function created with new Function does not close over the outer lexical environment β€” it closes over the global environment only.

πŸ”₯ Example with Closure Difference:

jsCopyEditfunction getFunc() {
  let secret = "hidden";

  return new Function('console.log(secret)');
}

getFunc()(); // ❌ ReferenceError: secret is not defined

But with a regular function:

function getFunc() {
  let secret = "hidden";

  return function() {
    console.log(secret); // βœ… works
  }
}
getFunc()(); // "hidden"

πŸ”Ή 2. Fill Any Gaps

βœ… Hidden Concepts and Advanced Mechanics

βœ… [[Environment]] Internal Slot

Every function in JS has a hidden [[Environment]] β€” it’s the lexical scope captured at creation time.

  • function() or arrow functions: capture current [[Environment]].

  • new Function(...): always captures global environment.

πŸ”₯ This means variables in outer scopes are inaccessible to new Function.


βœ… Quirks / Gotchas

🧨 1. Lack of Closure

let user = "Manoj";
let f = new Function('console.log(user)');
f(); // ❌ ReferenceError

🧨 2. Eval-like behavior

Using new Function is similar to eval():

  • It compiles code at runtime

  • Avoids capturing local scope

  • May be blocked in CSP (Content Security Policy)

🧨 3. Minifier Breakage Prevention

Minifiers rename local vars. If dynamic function creation accessed them, code could break post-minification.

🧨 4. No access to this unless explicitly passed

You must bind or pass this to use it inside:

let f = new Function('return this.value');
console.log(f.call({ value: 42 })); // 42

βœ… Browser Differences & Security

  • ⚠️ In CSP-restricted environments (script-src 'self'), new Function throws.

  • Chrome & Firefox treat it as unsafe in extensions.

  • Many JS linters warn against it.


πŸ”Ή 3. Challenge Me Deeply

🟒 Basic

  1. Create a function using new Function that multiplies two numbers.

  2. Create a new Function that alerts "Hello World" but does not take any parameters.

  3. Write a new Function that accepts a parameter and returns its square.

🟑 Intermediate

  1. Dynamically build a function that validates if a string contains a keyword (keyword is passed at runtime).

  2. Write a factory function that returns a new function based on a user-defined mathematical operation (+, -, *, /).

  3. Use new Function to implement a simple calculator: "3 * 5 + 2" β†’ 17.

πŸ”΄ Advanced

  1. Create a dynamic form validator that builds a custom validation function from string rules.

  2. Use new Function in a way that bypasses a minifier's renaming of a parameter.

  3. Construct a sandboxed execution system using new Function for plugin-like logic (no closures, secure).

  4. Build a code runner for user-written code snippets that can’t access internal app state.

🎯 Brain Twister

  1. Why does this fail?
function outer() {
  let secret = "top-secret";
  return new Function('return secret;');
}
console.log(outer()()); // ??

πŸ”Ή 4. Interview-Ready Questions

βœ… Conceptual

  • What is the difference between eval() and new Function()?

  • Why does new Function() not capture local variables?

  • What are the performance and security implications of using new Function()?

βœ… Debugging

  • A developer dynamically creates a function using new Function, but it can't access variables in their module β€” why?

  • You minified your JS app and now dynamic code that worked before fails β€” what happened?

βœ… Scenario-Based

  • You receive rules from a backend as strings and need to validate input β€” how would you do it safely?

  • If you use new Function in a browser extension, what are the security/CSP considerations?

βœ… Best Practices

πŸ‘ Impressive:

  • Avoiding new Function unless dynamic runtime code is truly needed

  • Using factory functions instead when closures are required

  • Sanitizing any string input used in dynamic function creation

πŸ‘Ž Red Flags:

  • Using new Function just to delay logic

  • Passing user input unsanitized β†’ XSS vulnerability

  • Using it in code meant to run in restricted environments


πŸ”Ή 5. Real-World Usage

βœ… Where it's used:

  • Form builders: Build field validation dynamically from schema

  • Template engines: Compile template into JS function (e.g., Handlebars precompilation)

  • No-code platforms: Let users write formula expressions that become executable code

  • Game engines: Allow scripted logic from external files

βœ… Examples

πŸ›  Lodash (older versions)

_.template('Hello <%= name %>') // compiles to a function

🧩 Vue / Angular templates

Older template compilers would optionally allow using new Function.


πŸ”Ή 6. Remember Like a Pro

🧠 Mnemonic:

"New Function = New Scope (Global Only)"

NFGS β€” New Function = Global Scope

⚑ Analogy:

new Function is like loading code from a script tag written at runtime β€” it doesn’t β€œsee” where it came from, only what’s in the global world.

🧾 Cheatsheet:

Featurefunction/arrownew Function
Scope CapturedLocalGlobal only
Closure Accessβœ… Yes❌ No
Minifier Safe❌ Riskβœ… Safe
Security RiskMediumHigh (CSP risk)
Code as String?βŒβœ… Yes
CSP-compatibleβœ…βŒ Often blocked

πŸ”Ή 7. Apply It in a Fun Way

πŸ§ͺ Mini Project: Dynamic Math Evaluator (like a custom calculator)

πŸ“¦ Goal:

Create a tool where users type something like "a + b * 2" and get a compiled function they can reuse.


πŸ›  Steps:

  1. Create a function buildEvaluator(expr: string) that returns a function.

  2. Use new Function('a', 'b', 'return ' + expr) inside.

  3. Let users provide a and b values and see results.

  4. Prevent code injection by sanitizing expr (e.g. only allow digits, variables, + - * /).


πŸš€ Extension Ideas:

  • Allow variables from a list, like x, y, z

  • Add safe mode using regex to disallow harmful keywords (document, eval, etc.)

  • Support functions like Math.sqrt, Math.pow


βž• Bonus

🧰 Open-Source Projects Using This Heavily

  • Lodash (_.template)

  • AngularJS $compile (legacy)

  • jQuery Templates (deprecated)

  • FormIO β€” dynamic form validation rules


🚨 Common Developer Mistakes

  • Thinking new Function can access outer scope (it can’t)

  • Using unsanitized strings from users (XSS)

  • Not understanding CSP violations (production error)

  • Assuming it's "better" than closures β€” it's not unless needed


πŸš€ Performance Tips

  • new Function has high creation cost β†’ avoid in hot paths

  • Prefer regular functions or closures if dynamic behavior isn't essential

  • Use caching if building many similar dynamic functions


βœ… Deprecated or Modern Alternatives?

  • βœ… Use Function only when runtime compilation is needed.

  • βœ… Use closures and factory functions instead where possible.

  • βœ… Use Web Workers or module loaders to isolate dynamic logic.


🧠 Summary Table

ConceptDetails
Function ScopeGlobal only
Lexical Env Closure❌ No β€” unlike regular functions
Creation StyleString-based
Use CasesTemplating, evaluators, plugin systems
RisksXSS, CSP violations, performance
AlternativesFactory functions, closures, arrow functions

More from this blog

JS Journey : Concepts & Challenges

57 posts