作用域&變數提升&閉包題目及內容解答

来源:https://www.cnblogs.com/smileZAZ/archive/2022/07/11/16466465.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1. 代碼輸出結果 (function(){ var x = y = 1; })(); var z; console.log(y); // 1 console.log(z); // undefined console.log(x); // ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

1. 代碼輸出結果

(function(){
   var x = y = 1;
})();
var z;

console.log(y); // 1
console.log(z); // undefined
console.log(x); // Uncaught ReferenceError: x is not defined

這段代碼的關鍵在於:var x = y = 1; 實際上這裡是從右往左執行的,首先執行y = 1, 因為y沒有使用var聲明,所以它是一個全局變數,然後第二步是將y賦值給x,講一個全局變數賦值給了一個局部變數,最終,x是一個局部變數,y是一個全局變數,所以列印x是報錯。

2. 代碼輸出結果

var a, b
(function () {
   console.log(a);
   console.log(b);
   var a = (b = 3);
   console.log(a);
   console.log(b);   
})()
console.log(a);
console.log(b);

輸出結果:

undefined 
undefined 
3 
3 
undefined 
3

這個題目和上面題目考察的知識點類似,b賦值為3,b此時是一個全局變數,而將3賦值給a,a是一個局部變數,所以最後列印的時候,a仍舊是undefined。

3. 代碼輸出結果

var friendName = 'World';
(function() {
  if (typeof friendName === 'undefined') {
    var friendName = 'Jack';
    console.log('Goodbye ' + friendName);
  } else {
    console.log('Hello ' + friendName);
  }
})();

輸出結果:Goodbye Jack

我們知道,在 JavaScript中, Function 和 var 都會被提升(變數提升),所以上面的代碼就相當於:

var name = 'World!';
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye ' + name);
    } else {
        console.log('Hello ' + name);
    }
})();

這樣,答案就一目瞭然了。

4. 代碼輸出結果

function fn1(){
  console.log('fn1')
}
var fn2
 
fn1()
fn2()
 
fn2 = function() {
  console.log('fn2')
}
 
fn2()

輸出結果: 

fn1
Uncaught TypeError: fn2 is not a function
fn2

這裡也是在考察變數提升,關鍵在於第一個fn2(),這時fn2仍是一個undefined的變數,所以會報錯fn2不是一個函數。

5. 代碼輸出結果

function a() {
    var temp = 10;
    function b() {
        console.log(temp); // 10
    }
    b();
}
a();

function a() {
    var temp = 10;
    b();
}
function b() {
    console.log(temp); // 報錯 Uncaught ReferenceError: temp is not defined
}
a();

在上面的兩段代碼中,第一段是可以正常輸出,這個應該沒啥問題,關鍵在於第二段代碼,它會報錯Uncaught ReferenceError: temp is not defined。這時因為在b方法執行時,temp 的值為undefined。

6. 代碼輸出結果

 var a=3;
 function c(){
    alert(a);
 }
 (function(){
  var a=4;
  c();
 })();

js中變數的作用域鏈與定義時的環境有關,與執行時無關。執行環境只會改變this、傳遞的參數、全局變數等

7. 代碼輸出問題

function fun(n, o) {
  console.log(o)
  return {
    fun: function(m){
      return fun(m, n);
    }
  };
}
var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);  c.fun(2);  c.fun(3);

輸出結果:

undefined  0  0  0
undefined  0  1  2
undefined  0  1  1

這是一道關於閉包的題目,對於fun方法,調用之後返回的是一個對象。我們知道,當調用函數的時候傳入的實參比函數聲明時指定的形參個數要少,剩下的形參都將設置為undefined值。所以 console.log(o); 會輸出undefined。而a就是是fun(0)返回的那個對象。也就是說,函數fun中參數 n 的值是0,而返回的那個對象中,需要一個參數n,而這個對象的作用域中沒有n,它就繼續沿著作用域向上一級的作用域中尋找n,最後在函數fun中找到了n,n的值是0。瞭解了這一點,其他運算就很簡單了,以此類推。

8. 代碼輸出結果

f = function() {return true;};   
g = function() {return false;};   
(function() {   
   if (g() && [] == ![]) {   
      f = function f() {return false;};   
      function g() {return true;}   
   }   
})();   
console.log(f());

輸出結果: false

這裡首先定義了兩個變數f和g,我們知道變數是可以重新賦值的。後面是一個匿名自執行函數,在 if 條件中調用了函數 g(),由於在匿名函數中,又重新定義了函數g,就覆蓋了外部定義的變數g,所以,這裡調用的是內部函數 g 方法,返回為 true。第一個條件通過,進入第二個條件。

第二個條件是[] == ![],先看 ![] ,在 JavaScript 中,當用於布爾運算時,比如在這裡,對象的非空引用被視為 true,空引用 null 則被視為 false。由於這裡不是一個 null, 而是一個沒有元素的數組,所以 [] 被視為 true, 而 ![] 的結果就是 false 了。當一個布爾值參與到條件運算的時候,true 會被看作 1, 而 false 會被看作 0。現在條件變成了 [] == 0 的問題了,當一個對象參與條件比較的時候,它會被求值,求值的結果是數組成為一個字元串,[] 的結果就是 '' ,而 '' 會被當作 0 ,所以,條件成立。

兩個條件都成立,所以會執行條件中的代碼, f 在定義是沒有使用var,所以他是一個全局變數。因此,這裡會通過閉包訪問到外部的變數 f, 重新賦值,現在執行 f 函數返回值已經成為 false 了。而 g 則不會有這個問題,這裡是一個函數內定義的 g,不會影響到外部的 g 函數。所以最後的結果就是 false。

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 一、操作系統 OS(Operating System)既操作系統,是一個包含通用目的或者功能的軟體程式,這些通用目的包含了以下幾項: 硬體驅動 記憶體管理 進程管理 網路管理 安全管理 文件管理 OS主要有三大分類,既伺服器OS、桌面OS以及移動設 ...
  • 分組查詢:關鍵字group by的用法 group:組 by:通過 group by :通過....。分組group by列名:通過指定列來分組 一般情況下在題目中出現 "每個" "各個" "不同的" 這一類詞語時基本都會用到group by 分組關鍵字 語法: select 列名 from表名 g ...
  • 一鍵直達直播間 一、直播介紹 之前的內容,我們為大家分享了Taier入門及控制台,以及Taier的Web前端架構介紹,本期我們為大家分享Taier數據開發介紹。 本次直播我們將從Taier的數據開發功能介紹,到任務運行、功能可擴展點以及未來將發佈的taier1.2為大家進行詳細講解,通過本次分享,希 ...
  • 01檢索數據 SQL60 從 Customers 表中檢索所有的 ID 編寫 SQL 語句,從 Customers 表中檢索所有的cust_id select * from Customers; SQL61 檢索併列出已訂購產品的清單 【問題】編寫SQL 語句,檢索併列出所有已訂購商品(prod_i ...
  • XR技術的發展,為用戶帶來了全新的體驗模式。那麼,作為支撐XR發展主要學科之一的圖形學,將迎來哪些發展新機遇?移動應用開發者,該如何擁抱3D數字化轉型? 7月15日,HDD·HMS Core. Sparkle應用創新分論壇將邀請圖形領域學者、分析師、技術和產品專家,共同探討圖形技術的發展現狀和趨勢, ...
  • JavaScript基本知識點——帶你逐步解開JS的神秘面紗 在我們前面的文章中已經深入學了HTML和CSS,在網頁設計中我們已經有能力完成一個美觀的網頁框架 但僅僅是網頁框架不足以展現出網頁的魅力,JS由此而生! JavaScript概述 JavaScript是一門弱類型腳本語言,其源代碼在發往客 ...
  • 純前端實現-tab卡片化樣式切換 html內容 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>選項卡切換</title> <link rel="stylesheet" type="text/css" href="./css ...
  • 實現思路: 用戶登錄時若勾選“記住我”功能選項,則將登錄名和密碼(加密後)存入本地緩存,下次登錄頁面載入時自動獲取保存好的賬號和密碼(需解密),回顯到登錄輸入框中。 說到存入本地緩存,大家想到的一定是cookies、localStorage、sessionStorage,不過後者我是不推薦使用的,咱 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...