口水話 閉包中this的指向

来源:http://www.cnblogs.com/betaSu/archive/2016/01/14/5129773.html
-Advertisement-
Play Games

前言:高程這本書真是神奇,每複習一遍,都會有新的收穫。話說我看書有個習慣,要是看得似懂非懂的地方就喜歡打個“?”。這次看到高程第七章“函數表達式”關於閉包與this對象的部分,發現已經積攢了2個問號了。之前過了兩遍都沒有完全弄明白! 好在如今對this的指向、函數的理解已經今非昔比,這一次終於讓我....


前言:高程這本書真是神奇,每複習一遍,都會有新的收穫。話說我看書有個習慣,要是看得似懂非懂的地方就喜歡打個“?”。這次看到高程第七章“函數表達式”關於閉包與this對象的部分,發現已經積攢了2個問號了。之前過了兩遍都沒有完全弄明白!

  好在如今對this的指向、函數的理解已經今非昔比,這一次終於讓我打通這條堵塞的經脈,讓他融入我的知識體系了!!想想真是有些小激動呢~~

目的:一句話,本文就是解釋為什麼如下兩篇代碼中this.name的指向不同。

var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          return function(){
            return this.name;
          };
        }
      };
alert(object.getNameFunc()());  //The Window
var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          var that = this;
          return function(){
            return that.name;
          };
        }
      };
alert(object.getNameFunc()());   //My Object

正文:首先,我們得知道當函數調用過程中發生了什麼。

  當函數被調用時,會自動創建兩個變數:this和arguments。這兩個變數有個特點,他們的搜索範圍僅限被調用函數的活動對象。什麼意思呢?arguments對象大家一定很清楚,保存函數的傳參的副本。看如下代碼:

function father (a) {
    var result=a;
    var result2=null;
    function son (a) {
        result2=a;
    }
    return result+" and "+result2;
}
father(123);  //"123 and null"

  這裡創建了兩個函數,father和son,其中son作為father函數內部的函數。 他們都接受傳參a。在這裡我們傳入傳參123,返回father與son獲得的傳參結果。

  結果顯示father的傳參為123,而son的傳參為null,這個結果是顯而易見的。在這裡貼這麼弱智的代碼的用意是想說明son在搜索a這個變數時只搜索自己的活動變數而不會通過作用域鏈向上到father中去搜索。同樣的道理使用於this。

var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          return function(){
            return this.name;
          };
        }
      };
alert(object.getNameFunc()());  //The Window

  這裡最內層匿名函數this為什麼指向的是window而不是他的上層函數getNameFunc。之前已經說明瞭this作為特殊的變數他的搜索範圍同arguments一樣僅限於自身的活動對象。也就是說內層匿名函數的this就算在自己這兒搜不到結果也不會再去他的上層函數getNameFunc中搜索。這個問題可以等同於——最內層匿名函數的this為什麼指向的是window?

  如果我們將最後的結果賦給一個變數來說明會簡單汗多。

var result=object.getNameFunc()();

  result變數是一個全局變數,他保存的指針指向getNameFunc最內層匿名函數的結果。訪問這個變數其實調用的不是getNameFunc函數,而是getNameFunc內部的匿名函數。也就是說這個匿名函數是在全局作用域中調用的,那麼匿名函數的this理所當然的指向window。

  有了前面的解釋,第二段代碼就很好解釋了。

var name = "The Window";
      var object = {
        name : "My Object",
        getNameFunc : function(){
          var that = this;
          return function(){
            return that.name;
          };
        }
      };
alert(object.getNameFunc()());   //My Object

  getNameFunc函數用that變數保存了他的this的指向,併在匿名函數中調用that變數。匿名函數在自己的活動對象中搜索到了that,並向上通過作用域鏈找到了that的出處。結果就顯而易見了。


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

-Advertisement-
Play Games
更多相關文章
  • 第1節 列表列表和元組的主要區別在於,列表是可以修改的,元組則不能。說白了就是要求添加元素,那麼就選擇列表;不能修改則選擇元組。如:l1 = ['alex',18]l2 = [['alex',18],['eric',19]]num = [1,2,3,4,5,6,7,8,9,10]列表的操作索引(下標...
  • 一. 定義 1. 享元模式是池技術的一種實現方式,使用共用對象來支持細粒度的對象 2. 享元模式把對象信息分為了兩個部分 (1)內部狀態 : 可以作為對象的動態附加信息,不必存儲在具體的對象中的屬性(id,postAddress) (2)外部狀態 : 對象得以依賴的一個標記,隨環境改變而改變...
  • 強調標簽:斜體強調 粗體強調 直接用span控制也可以實現該效果 font-size font-weight分行標簽:水平橫線標簽: 效果: ...
  • 構造器模式簡單描述(看圖): 構造器用於創建特定類型對象——準備好對象以備使用,同時接收構造器可以使用的參數,以在第一次創建對象時,設置成員屬性和方法的值 1、創建對象 新對象創建的兩種方法 <code var newObject={}; var newObject=new object();...
  • 這裡要介紹的是一個jQuery插件:jquery.easysector.jsHtml5提供了強大的繪圖API,讓我們能夠使用javascript輕鬆繪製各種圖形。本文將主要講解使用HTML5繪製餅圖(統計圖)的方法。先看一下餅圖效果:http://hovertree.com/texiao/easys...
  • 1:接受文件http://stackoverflow.com/questions/24610996/how-to-get-uploaded-file-in-node-js-express-app-using-angular-file-upload可以用下列的第三方庫busboyandconnect-...
  • 時代的變遷,創業的大潮,越來越多的人關註了有點開發,越來越多的人瞭解了互聯網服務術語:PaaS、IaaS、SaaS、BaaS等。今天大家在開發App的時候這麼多複雜的雲服務如何來選擇呢?IaaS服務商大家提起馬上能想到的一定就是“阿裡雲”、“騰訊雲”、“微軟Azure”、“AWS”。這些都是IaaS...
  • 灌水評論示例:var http = require('http');var querystring = require('querystring');var postData = querystring.stringify({ content: '不錯不錯', cid: 348});va...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...