{"id":39304,"date":"2025-11-17T12:44:41","date_gmt":"2025-11-17T20:44:41","guid":{"rendered":"https:\/\/cloudinary.com\/blog\/?p=39304"},"modified":"2025-12-12T15:20:31","modified_gmt":"2025-12-12T23:20:31","slug":"what-is-lexical-scope-in-javascript","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/","title":{"rendered":"What is Lexical Scope in JavaScript?\u00a0"},"content":{"rendered":"\n<p>Many JavaScript bugs come from variables not being where you think they are. If you have ever logged a value in a callback and seen something unexpected, or watched all your button handlers print the same index, you have met lexical scope.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Question:<\/h2>\n\n\n\n<p><em>I keep hearing that \u201cJS has lexical scope\u201d and that it explains closures, var vs let behavior, and those loop bugs where every click handler logs the same number. What is lexical scope in JavaScript, how does it affect variable access and closures, and what are the best practices to avoid surprises? Code examples would be great.<\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Answer:<\/h2>\n\n\n\n<p>Lexical scope is the rule that determines where variables are accessible based on where they are written in the source code. JavaScript decides scope at <em>parse time<\/em>, not at runtime, using nested blocks and functions to form a scope chain. A function can read variables from its own scope and any outer scopes, but not from inner scopes it does not contain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Core Idea<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Scopes are created by functions and by blocks delimited with braces when using let or const.<\/li>\n\n\n\n<li>Inner scopes can access variables defined in outer scopes. The reverse is not true.<\/li>\n\n\n\n<li>Closures happen when a function remembers variables from the scope where it was defined.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Example: Nested Scopes<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">const<\/span> greeting = <span class=\"hljs-string\">\"Hi\"<\/span>;\n\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">outer<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> name = <span class=\"hljs-string\">\"Ava\"<\/span>;\n\u00a0 <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">inner<\/span>(<span class=\"hljs-params\"><\/span>) <\/span>{\n\u00a0 \u00a0 <span class=\"hljs-built_in\">console<\/span>.log(greeting, name); <span class=\"hljs-comment\">\/\/ \"Hi Ava\"<\/span>\n\u00a0 }\n\u00a0 inner();\n}\n\nouter();\n<span class=\"hljs-comment\">\/\/ inner(); \/\/ ReferenceError - inner is not in this scope<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">var vs. let\/const and Block Scope<\/h3>\n\n\n\n<p><code>var<\/code> is function-scoped. <code>let<\/code> and <code>const<\/code> are block-scoped. This difference explains the infamous loop-handler bug:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Problem: var leaks one binding across the loop<\/span>\n<span class=\"hljs-keyword\">const<\/span> buttons = <span class=\"hljs-built_in\">document<\/span>.querySelectorAll(<span class=\"hljs-string\">\"button\"<\/span>);\n<span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">var<\/span> i = <span class=\"hljs-number\">0<\/span>; i &lt; buttons.length; i++) {\n\u00a0 buttons&#91;i].addEventListener(<span class=\"hljs-string\">\"click\"<\/span>, () =&gt; <span class=\"hljs-built_in\">console<\/span>.log(i));\n}\n<span class=\"hljs-comment\">\/\/ All handlers print buttons.length<\/span>\n\n<span class=\"hljs-comment\">\/\/ Fix 1: use let to create a new binding per iteration<\/span>\n<span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">let<\/span> j = <span class=\"hljs-number\">0<\/span>; j &lt; buttons.length; j++) {\n\u00a0 buttons&#91;j].addEventListener(<span class=\"hljs-string\">\"click\"<\/span>, () =&gt; <span class=\"hljs-built_in\">console<\/span>.log(j));\n}\n\n<span class=\"hljs-comment\">\/\/ Fix 2: IIFE creates a new scope for each i<\/span>\n<span class=\"hljs-keyword\">for<\/span> (<span class=\"hljs-keyword\">var<\/span> k = <span class=\"hljs-number\">0<\/span>; k &lt; buttons.length; k++) {\n\u00a0 (<span class=\"hljs-function\">(<span class=\"hljs-params\">n<\/span>) =&gt;<\/span> buttons&#91;n].addEventListener(<span class=\"hljs-string\">\"click\"<\/span>, () =&gt; <span class=\"hljs-built_in\">console<\/span>.log(n)))(k);\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Closures in 1 Minute<\/h3>\n\n\n\n<p>A closure is a function bundled with references to its surrounding scope. The closed-over variables continue to live as long as the function does.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">makeCounter<\/span>(<span class=\"hljs-params\">start = <span class=\"hljs-number\">0<\/span><\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">let<\/span> count = start;\u00a0 \u00a0 \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ captured by the inner function<\/span>\n\u00a0 <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-function\"><span class=\"hljs-params\">()<\/span> =&gt;<\/span> ++count; \u00a0 \u00a0 <span class=\"hljs-comment\">\/\/ closure<\/span>\n}\n\n<span class=\"hljs-keyword\">const<\/span> next = makeCounter(<span class=\"hljs-number\">10<\/span>);\n<span class=\"hljs-built_in\">console<\/span>.log(next()); <span class=\"hljs-comment\">\/\/ 11<\/span>\n<span class=\"hljs-built_in\">console<\/span>.log(next()); <span class=\"hljs-comment\">\/\/ 12<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Hoisting and the Temporal Dead Zone<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Function declarations and <code>var<\/code> are hoisted. The variable exists before its line of code, but var initializes to undefined.<\/li>\n\n\n\n<li><code>let<\/code> and <code>const<\/code> are hoisted too, but they are not accessible before their declaration line, which means accessing them early triggers a <code>ReferenceError<\/code>. This period is the temporal dead zone.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Common Pitfalls and Quick Fixes<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Accidental globals. <\/strong>Always declare with const or let to avoid creating globals on window.<\/li>\n\n\n\n<li><strong>Name shadowing. <\/strong>Avoid redeclaring the same name in nested scopes unless intentional.<\/li>\n\n\n\n<li><strong>Asynchronous callbacks<\/strong>. Use <code>let<\/code> in loops or capture values in a new function scope.<\/li>\n\n\n\n<li>Create pure functions and small modules to keep scope trees shallow and readable.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Where This Matters in Real Apps<\/h3>\n\n\n\n<p>Frontend code that wires event handlers, fetches data, or builds media URLs relies on closures to carry context. For example, when building dynamic image URLs for delivery, lexical scope lets you encapsulate parameters while returning a tiny helper.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ Simple Cloudinary-style URL factory using lexical scope<\/span>\n<span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">makeImageUrl<\/span>(<span class=\"hljs-params\">{ cloudName, publicId }<\/span>) <\/span>{\n\u00a0 <span class=\"hljs-keyword\">const<\/span> base = <span class=\"hljs-string\">`https:\/\/res.cloudinary.com\/<span class=\"hljs-subst\">${cloudName}<\/span>\/image\/upload\/`<\/span>;\n\u00a0 <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-function\">(<span class=\"hljs-params\">transforms<\/span>) =&gt;<\/span> <span class=\"hljs-string\">`<span class=\"hljs-subst\">${base}<\/span><span class=\"hljs-subst\">${transforms}<\/span>\/<span class=\"hljs-subst\">${publicId}<\/span>`<\/span>;\n}\n\n<span class=\"hljs-keyword\">const<\/span> toWebP600 = makeImageUrl({ <span class=\"hljs-attr\">cloudName<\/span>: <span class=\"hljs-string\">\"demo\"<\/span>, <span class=\"hljs-attr\">publicId<\/span>: <span class=\"hljs-string\">\"sample.jpg\"<\/span> });\n<span class=\"hljs-keyword\">const<\/span> url = toWebP600(<span class=\"hljs-string\">\"c_fill,w_600,f_webp\"<\/span>);\n<span class=\"hljs-comment\">\/\/ Use with &lt;img src=\"url\"&gt; or your framework's image component<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>If you are rendering images in markup, see this quick refresher on the <a href=\"https:\/\/cloudinary.com\/guides\/image-effects\/html-image-tag\">HTML image tag<\/a>. When delivering media at scale, understanding hosting basics helps pick the right architecture and cache strategy, as covered in <a href=\"https:\/\/cloudinary.com\/guides\/web-performance\/understanding-image-hosting-for-websites\">Understanding image hosting for websites<\/a>.&nbsp;<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Debugging Tips<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Log values right where you capture them to confirm what the closure sees.<\/li>\n\n\n\n<li>Search for var in loops and convert to let where appropriate.<\/li>\n\n\n\n<li>Use linters to catch accidental globals and shadowed variables.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">TL;DR<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Lexical scope means variables are available where they are declared and in nested scopes.<\/li>\n\n\n\n<li>let and const are block-scoped and avoid loop-closure bugs. var is function-scoped and trickier.<\/li>\n\n\n\n<li>Closures let functions remember outer variables. Great for factories, handlers, and configuration.<\/li>\n\n\n\n<li>Keep scopes small, avoid accidental globals, and favor clear, scoped helpers for reliability.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Learn More<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/cloudinary.com\/tools\/png-to-webp\">PNG to WebP Converter<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/tools\/jpg-to-webp\">JPG to WebP Converter<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/tools\/image-upscale\">Image Upscaling and Quality Enhancement<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/cloudinary.com\/tools\/image-to-webp\">Image to WebP Converter<\/a><\/li>\n<\/ul>\n\n\n\n<p>Ready to build faster, more reliable frontend code and deliver optimized media at scale? <a href=\"https:\/\/cloudinary.com\/users\/register_free\">Sign up for a free Cloudinary account<\/a> and start transforming and delivering assets with confidence.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Many JavaScript bugs come from variables not being where you think they are. If you have ever logged a value in a callback and seen something unexpected, or watched all your button handlers print the same index, you have met lexical scope. Question: I keep hearing that \u201cJS has lexical scope\u201d and that it explains [&hellip;]<\/p>\n","protected":false},"author":88,"featured_media":39267,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[423],"class_list":["post-39304","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","tag-questions"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>What is Lexical Scope in JavaScript?\u00a0<\/title>\n<meta name=\"description\" content=\"Many JavaScript bugs come from variables not being where you think they are. If you have ever logged a value in a callback and seen something unexpected,\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"What is Lexical Scope in JavaScript?\u00a0\" \/>\n<meta property=\"og:description\" content=\"Many JavaScript bugs come from variables not being where you think they are. If you have ever logged a value in a callback and seen something unexpected,\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-17T20:44:41+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-12-12T23:20:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA\" \/>\n\t<meta property=\"og:image:width\" content=\"1999\" \/>\n\t<meta property=\"og:image:height\" content=\"1100\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"damjanantevski\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/\"},\"author\":{\"name\":\"damjanantevski\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/43592e43c12520a1e867d456b1e8cf7e\"},\"headline\":\"What is Lexical Scope in JavaScript?\u00a0\",\"datePublished\":\"2025-11-17T20:44:41+00:00\",\"dateModified\":\"2025-12-12T23:20:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/\"},\"wordCount\":595,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA\",\"keywords\":[\"Questions\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/\",\"name\":\"What is Lexical Scope in JavaScript?\u00a0\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA\",\"datePublished\":\"2025-11-17T20:44:41+00:00\",\"dateModified\":\"2025-12-12T23:20:31+00:00\",\"description\":\"Many JavaScript bugs come from variables not being where you think they are. If you have ever logged a value in a callback and seen something unexpected,\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#primaryimage\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA\",\"width\":1999,\"height\":1100},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"What is Lexical Scope in JavaScript?\u00a0\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/43592e43c12520a1e867d456b1e8cf7e\",\"name\":\"damjanantevski\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/3b40c995531fe4d510212a06c9d4fc666d2cb8efbfebc98a94191701accf4817?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/3b40c995531fe4d510212a06c9d4fc666d2cb8efbfebc98a94191701accf4817?s=96&d=mm&r=g\",\"caption\":\"damjanantevski\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"What is Lexical Scope in JavaScript?\u00a0","description":"Many JavaScript bugs come from variables not being where you think they are. If you have ever logged a value in a callback and seen something unexpected,","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/","og_locale":"en_US","og_type":"article","og_title":"What is Lexical Scope in JavaScript?\u00a0","og_description":"Many JavaScript bugs come from variables not being where you think they are. If you have ever logged a value in a callback and seen something unexpected,","og_url":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/","og_site_name":"Cloudinary Blog","article_published_time":"2025-11-17T20:44:41+00:00","article_modified_time":"2025-12-12T23:20:31+00:00","og_image":[{"width":1999,"height":1100,"url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA","type":"image\/jpeg"}],"author":"damjanantevski","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/"},"author":{"name":"damjanantevski","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/43592e43c12520a1e867d456b1e8cf7e"},"headline":"What is Lexical Scope in JavaScript?\u00a0","datePublished":"2025-11-17T20:44:41+00:00","dateModified":"2025-12-12T23:20:31+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/"},"wordCount":595,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA","keywords":["Questions"],"inLanguage":"en-US","copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/","url":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/","name":"What is Lexical Scope in JavaScript?\u00a0","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#primaryimage"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA","datePublished":"2025-11-17T20:44:41+00:00","dateModified":"2025-12-12T23:20:31+00:00","description":"Many JavaScript bugs come from variables not being where you think they are. If you have ever logged a value in a callback and seen something unexpected,","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#primaryimage","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA","width":1999,"height":1100},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/questions\/what-is-lexical-scope-in-javascript\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"What is Lexical Scope in JavaScript?\u00a0"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/43592e43c12520a1e867d456b1e8cf7e","name":"damjanantevski","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/3b40c995531fe4d510212a06c9d4fc666d2cb8efbfebc98a94191701accf4817?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/3b40c995531fe4d510212a06c9d4fc666d2cb8efbfebc98a94191701accf4817?s=96&d=mm&r=g","caption":"damjanantevski"}}]}},"jetpack_featured_media_url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1763149247\/QA_javascript_featured_image\/QA_javascript_featured_image.jpg?_i=AA","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/39304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/88"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=39304"}],"version-history":[{"count":2,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/39304\/revisions"}],"predecessor-version":[{"id":39612,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/39304\/revisions\/39612"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media\/39267"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=39304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=39304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=39304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}