論JavaScript的作用域

来源:http://www.cnblogs.com/cqhaibin/archive/2017/09/03/7470597.html
-Advertisement-
Play Games

一直以來本人認為想深入瞭解一門語言,不光是讓自己變成擼sir,更需要時間的錘煉。能經得起時間考驗的東西更值得擁有。學習和使用Javascript一晃都7年了,最近才感覺自己對他才有頓悟,不知道是否來得有點遲。本文歸納了我對 JS中作用的理解,希望得學習有所幫助。 特別說明:這是從另一個側面(函數域的 ...


     一直以來本人認為想深入瞭解一門語言,不光是讓自己變成擼sir,更需要時間的錘煉。能經得起時間考驗的東西更值得擁有。學習和使用Javascript一晃都7年了,最近才感覺自己對他才有頓悟,不知道是否來得有點遲。本文歸納了我對 JS中作用的理解,希望得學習有所幫助。

    特別說明:這是從另一個側面(函數域的覆蓋範圍)來解釋和說明執行上下文。

一、作用域的理論理解

     從入門Javascript時,無論是學校老師,還是你工作的老司機,都會很認真的考慮你,Js中有一個全局作用域,然後他包含很多的子域(如:由function、object創建作用域的),子域是可以很輕鬆的訪問父級域中的任何對象。這種表述你是否感覺很是空洞,難以理解。今本人就用浩瀚無邊的地域來舉個粟子:

通過上面這個Image,讓我一步一步帶你領略作用域的魅力。

1. 首先,地球:我們大家都很熟悉,他包含著你,我,以及世界上所有的國家(這兒就不論宇宙,否則會Hold不住),這肯定就是Js中的全局作用域了。地球包含天空、空氣,正如Js中全局作用包含包含Number、String、Function、Object、Boolean、Regex等對象。

2. 再者:中國、美國、北韓是三個平等的子作用域,他們都有利用地球 這個全局作用域的權利,如發射衛星。但美國再看不懂北韓,也不可能到北韓去乾什麼事情的。如Js的子作用域中可以任意使用Number、String等對象,但是沒辦法直接調用一個作用域平級的對象的方法。

3. 再次:你做為一個中國公民,可以依法使用中國內部的資源(只不過要麼交錢買,要麼就是拿了稅的),如果你想買點美國的的東西,那就需要new一個什麼寶、或者什麼東的來做中國與美國之間的引用,然後您懂的。如Js中需要訪問一個平級作用域的內容時,那你就需要拿到被訪問的引用。

4. 最後:bind,apply,call,可以這樣理解,bind就是在正規海購實體商場東西(預先可以看到實體的物品),而apply和call則是代購(只能視頻看)。bind改變一個作用但此函數不會立刻執行,而apply和call則會立刻執行。

二、示例代碼說明作用域

function Card(){
            this.name = 'name';
        }
        Card.prototype.getName =function(callback){
            callback();
            return this.name;
        }

        function PostCard(card){
            this.name = "postCard"
            this.card =card;
        }
        PostCard.prototype.getName =function(){
            var _name = this.card.getName(function(){
                console.log("callback: " + this.name);
            });
            console.log(_name + "  " + this.name);
        }

        var card = new Card();
        var postCard = new PostCard(card);
        postCard.getName();

1. 上述代碼Card和PostCard就像第一部分提及的中國、美國一樣,他們都有一個共同的父級作用域,就是window(地球)

2. Card和PostCard是平級作用域,如PostCard的getName方法想訪問Card的getName方法,就需要拿到Card的引用,如PostCard構造函數傳入的card實例就是為了完成這個事情。

3. Card的getName接受一個callback的高階函數(這又是另外一個話題,函數式編程了),這裡只要記住傳入就是一個類型為function的形參就行了。然後在Card的getName方法中執行了callback,但這裡你要註意,執行callback時沒有通過任何方式或手段來指定他的作用域,所以callback執行作用域為window(地球)。

4.輸出結果:

callback:
name    postname

三、示例代碼說明bind\apply\call

function Direction(){
            this.direction = "mid";
        }
        Direction.prototype.set =function(val){
            this.direction = val;
        }

        var direction = new Direction();
        var dir02 = new Direction();
        direction.set.call(direction, "right");
        direction.set.apply(dir02, ["bottom"]);

        console.log(direction.direction);
        console.log(dir02.direction);

        //bind
        var tmp = direction.set.bind(dir02);
        tmp("bind after");
        console.log('..........................');
        console.log(direction.direction);
        console.log(dir02.direction);

本示例代碼提供了一個Direction函數,然後對this(當前實例)綁定了direction屬性,且在Direction原型上綁定了set方法(用於修改this上的direction).

1. 通過 new 創建了Direction的兩個實例direction,dir02

2. 通過call和apply改變作用域的指向,進行set方法的執行,call指向了direction實例,而apply指向了dir02的實例。這也展示了call與apply的區別,就是參數傳送用一個列表,一個是數組。

3. 通過輸出結果大家會發現,雖然都是調用direction實例的set方法,但改變的this.direction卻是對應的實例屬性。

4. 通過bind方法把direction實例的set方法與dir02相綁定,然後執行這個綁定,會發現改變是仍然是dir02實例的direction屬性。

5. 輸出結果

right

bottom
scope
..........................
right
bind after

四、作用域的總結

1. 只有一個全局作用域,但有無數個子作用域。

2. 作用域的創建與執行:

   2.1 創建階段[函數被調用,但內部代碼還沒開始執行]

   2.2 創建 作用域鏈

   2.3 創建變數  函數 以及參數

   2.4 決定this的值(也就是作用域,或者是執行上下文)

   2.5 代碼執行[賦值、尋找函數引用以及解釋/執行代碼]


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

-Advertisement-
Play Games
更多相關文章
  • javascript(JS)的組成? DOM 文檔對象模型 BOM 瀏覽器對象模型 ECMAScript javascript(JS)在頁面中處理了什麼事情? 特效交互 數據交互 邏輯操作 常見特效的原理 通過js修改元素的css樣式,來操作元素的變化 js可以寫在哪 寫在寫標簽內部,行間事件(不允 ...
  • ###理解對象 ECMA-262把對象定義為:“無序屬性的集合,其屬性可以包含基本值、對象或者函數。”嚴格來講,這就相當於說對象是一組沒有特定順序的值。對象的每個屬性或方法都有一個名字,而每個名字都映射到一個值。 我們可以把ECMAScript的對象想象成散列表:無非就是一組名值對,其中的值可以是數 ...
  • 概述 對於企業級後臺產品來說,Table 應該是使用最頻繁的組件了,它通常比 Form 和 Chart 的使用還頻繁。對於這麼一個常用的組件,我們決定要把它從 RSuite 中單獨出來開發,並且要具有一定的通用性,適應很多場景。 首先看一下,Table 完成的效果。 預覽地址: https://rs ...
  • 粗體判斷js中的數據類型有一下幾種方法:typeof、instanceof、 constructor、 prototype、 $.type()/jquery.type(),接下來主要比較一下這幾種方法的異同。 先舉幾個例子: var a = "iamstring.";var b = 222;var ...
  • 在實際開發中,經常需要為Dom元素綁定事件,如果頁面上有4個li元素,點擊對應的li,彈出對應的li內容,怎麼做呢?是不是很簡單? 大多數人的做法都是:獲取元素,綁定事件 如果頁面上有1w個元素, 甚至10w個元素呢? 繼續使用上述方式,會有很大的性能問題,這個時候,有人可能要問,實際中的項目 哪有 ...
  • javascript作為一個面向對象的語言,理解 對象、原型、閉包、模塊模式等技術點對於成為一名合格的javascript程式員相當重要,多年沒寫過blog,今天就先拋個玉,在下基本也不做前端,但頗感興趣,願意和大家一起學習。此篇只是對自己認為的比較重要的知識點進行了說明,連貫性不是特別好,大家共同 ...
  • 這兩天在學習HTML5+CSS3樣式,按老師的作業做了一個魔方! ...
  • 在web開發中有以下幾種情況會出現 405的錯誤; 1 在前端的請求方式與後臺的不匹配: 例如後臺通過post方式,而你在前端用get方式則會出現405的錯誤。這樣只要讓他們 保持一致就不會報錯。 2 在前端提交的請求參數與後端不一致: 在很多時候我們會在請求路徑後面拼接幾個參數,一旦我們拼接的參數... ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...