1. 程式人生 > >JS學習筆記——作用域鏈

JS學習筆記——作用域鏈

1. 作用域鏈概念

涉及名詞:
執行環境(execution context)
變數物件(variable object)
作用域鏈(scope chian)
活動物件(activation object)
執行環境定義(execution context)了js可以訪問到的函式和變數,這些函式和變數都儲存在變數物件(variable object)中。每個執行環境都有一個變數物件與之相對應。
在web瀏覽器中,全域性環境是window物件。所以我們在全域性環境下定義的函式和變數都是在window物件裡建立的。
每個函式都在自己的執行環境,當多個函式巢狀時,也會有多個執行環境巢狀,那麼這一串的執行環境(變數物件)就會產生一個作用域鏈(scope chian),就像一串連結串列,把物件變數都串聯起來。當js剛進入函式中時,函式的活動物件(activation object)會被作為變數物件,此時的活動物件裡只有一個變數,即arguments物件(這個物件在window物件中不存在)。

var v = "win";
function foo() {
    var v = "foo";
    bar();

    function bar() {
        var v = "bar";
        console.log(v);
    }
}

foo();
//輸出bar

左邊表示作用域鏈,右邊表示變數物件。當js遇到一個符號時,它會先在當前的變數物件裡去搜索,如果找不到,再到上一層去搜索,直到window變數物件。查詢變數可以從巢狀的裡層擴充套件到外層,反過來就行不通了,連結串列是單向的。




如果定義變數的時候,沒有var關鍵字,那麼這個變數就被新增到window全域性變數物件中。
function
foo() {
v_g = "v_g"; console.log(window.v_g); } foo(); //輸出v_g

2. 延長作用域鏈

  1. try-catch語句
  2. eval語句
  3. with語句(MDN已不推薦使用)
//eval()的引數應該是字串,然後返回計算出的表示式的值,eval用到的地方不多,如果用於計算數值,js本身就可以計算數值。eval函式本身也有慢(需要喚起js直譯器)、不安全(字串可能被篡改成惡意程式碼)等缺點。
eval(new String('2 + 2')); // returns a String object containing "2 + 2"
eval('2 + 2'); // returns 4 //在with語句中,物件Math被加到作用域鏈的最前端,所有變數都要先在Math裡搜尋一遍,如果找不到,再到上一層搜尋。所以我們可以直接使用Math物件裡面的PI、sin、cos。 var a, x, y; var r = 10; with (Math) { a = PI * r * r; x = r * cos(PI); y = r * sin(PI / 2); }

3. 改變函式作用域

  1. apply()函式
  2. call()函式
  3. bind()函式

在全域性函式中呼叫函式,函式內的this等於window,即使函式嵌套了幾層;呼叫物件的方法,該方法中的this等於window。我們使用這三個函式,可以改變函式的作用域,使得函式執行在我們希望的那個環境裡。上述三個函式都屬於函式的方法
call()和apply()都是將函式的執行環境改變為第一個引數,他們的區別僅在第二個引數不同:call()需要把第2、3…個引數全部都列出來,而apply()可以傳一個數組或者argument。
bind()函式會建立一個新的函式例項,這個函式綁定了執行環境this,即使這個函式在全域性環境中執行,this指向已經繫結好的環境,而不是指向window。

window.color = "red";
var o = {color:"blue"};

function sayColor(){
    alert(this.color);
}

sayColor();             //red
sayColor.call(this);    //red
sayColor.call(window);  //red
sayColor.call(o);       //blue

var objectSayColor = sayColor.bind(o);
objectSayColor();       //blue

相關推薦

JS學習筆記——作用

1. 作用域鏈概念 涉及名詞: 執行環境(execution context) 變數物件(variable object) 作用域鏈(scope chian) 活動物件(activation object) 執行環境定義(execution cont

JS詳細圖解作用與閉包

function 就會 挑戰 timer 重新 http 哈哈 comment bject JS詳細圖解作用域鏈與閉包 攻克閉包難題 初學JavaScript的時候,我在學習閉包上,走了很多彎路。而這次重新回過頭來對基礎知識進行梳理,要講清楚閉包,也是一個非常大的

JS高級——作用

基本 post 函數 bsp func scope 多個 gpo var 基本概念 1、只要是函數就可以創造作用域 2、函數中又可以再創建函數 3、函數內部的作用域可以訪問函數外部的作用域 4、如果有多個函數嵌套,那麽就會構成一個鏈式訪問結構,這就是作用域鏈 <sc

c++學習筆記----作用

在C++中,作用域分為5類:   塊:用 { } 表示邊界,塊中的變數為區域性變數,形參也是區域性變數。大塊包小塊時,區域性變數優先使用變數值。   檔案:在函式外定義的變數稱為全域性變數,全域性變數的作用域稱為檔案作用域,在整個檔案中訪問;         函式原型:i

JS 通過沿著作用還是原型查詢變數

這是一道非常典型的JS閉包問題,結果和具體的解析請看這裡。對於其中的`函式作用域鏈的問題`博主似乎沒有解釋清楚,有一些疑問:js中的變數到底是沿著作用域鏈還是原型鏈查詢呢?首先,要分清作用域鏈與原型鏈的區別,簡單來說作用域鏈是相對於函式的,原型鏈是相對於物件的js中訪問變數有

js學習筆記01-函數,作用,閉包

學習筆記${var} //變量的占位符, ${}裏邊 依舊是js,字符串拼接 var str1 = "Hello"; var str2 = "World"; console.log("say: "+str1+" "+str2+"!"); console.log(`say: ${str1} ${str2}!`)

珠峰JS筆記1.1(預解釋,作用,this)

{ js 資料型別 基本資料型別:number, string , boolean, undefined, null 引用資料型別: {} 物件 , [ ] 陣列, /**/ 正則, Date, function 本質區別: 基本資料型別是按值來操作的,而

js學習筆記-第二章變數、作用和記憶體問題-執行環境和作用

//執行環境:執行環境(execution context,為簡單起見,有時也稱為“環境”)是 JavaScript 中最為重要的一個概念。執行環境定義了變數或函式有權訪問的其他資料,決定了它們各自的行為 //變數物件:。每個執行環境都有一個與之關聯的變數物件(variable object

Javascript高階程式設計學習筆記(10)—— 作用作用

昨天介紹了,JS中函式的作用域 什麼詞法環境之類的,可能很多小夥伴不太明白。 在今天的內容開始之前,先做個簡短的宣告:   詞法環境這一概念是在ES5中提出的,因為詞法環境主要用於儲存let、const宣告的變數、函式 而在ES3中對變數相關的資訊都儲存在變數物件上; 從功能上來說變數物

【Vue.js學習筆記】11:元件中CSS的作用

樣式表最終的生成位置 有兩個元件,一個是根元件App,一個是子元件Users。它們都有一個h2標籤,先只在根元件上寫CSS樣式。 App.vue <template> <div id="app"> <h2>父元件的h2標籤<

js學習筆記js變數作用

-js使用靜態作用域:只與變數宣告位置有關,而與函式執行順序無關 -js沒有塊級作用域:沒有for、if這種塊級作用域 -ES5中使用詞法環境管理靜態作用域 一、詞法環境: 1、組成: -環境記錄(形參、變數、函式等) -對外部詞法環境的引用(outer) 2、一段程式碼開

JS作用與原型

加載 obj tro 作用域鏈 繼承 exec 變量 賦值 js代碼 來一波,好記性不如爛筆頭。 這兩條鏈子可是很重要的。 作用域鏈 當執行一段JS代碼(全局代碼或函數)時,JS引擎會創建為其創建一個作用域又稱為執行上下文(Execution Context),在頁面加載後

js作用作用

性能 使用 plain 賦值 function keyword ack 全局變量 pla JavaScript的作用域和作用域鏈。在初學JavaScript時,覺得它就和其他語言沒啥區別,尤其是作用域這塊,想當然的以為“全局變量就是在整個程序的任何地方都可以訪問,也就是寫在

[js]作用查找規則獲取值和設置值

作用域鏈 markdown down ons 獲取值 pos script js代碼 window 作用域鏈查找規則獲取值和設置值 <script> /** 1.作用域鏈查找規則 私有作用域出現的一個變量不是私有的,則往上一級作用域查找,上級作用域沒有

關於JS裏的函數作用的總結

函數表達式 內存 環境 eat 你在 IT 總結 代碼 我們   在JavaScript中,函數的作用域鏈是一個很難理解的東西。這是因為JavaScript中函數的作用域鏈和其他語言比如C、C++中函數的作用域鏈相差甚遠。本文詳細解釋了JavaScript中與函數的作用域鏈

什麽是作用,什麽是原型,它們的區別,在js中它們具體指什麽?

function fun 創建 原型鏈 變量 pro pos bject prototype 作用域是針對變量的,比如我們創建了一個函數,函數裏面又包含了一個函數,那麽現在就有三個作用域   全局作用域==>函數1作用域==>函數2作用域 作用域的特點就是,先在

js內存空間 執行上下文 變量對象詳解 作用與閉包 全方位解讀this

變量 詳解 tail bsp pin 上下 AR detail net 內存空間:https://blog.csdn.net/pingfan592/article/details/55189622 執行上下文:https://blog.csdn.net/pingfan592

js 延長作用

debug urn true () AR title 包含 cati 因此 function buildUrl() { var qs = "?debug=true"; with (location) { var url = href + qs; }

js作用以及全局變量和局部變量

全局對象 作用 efi ren inter java tin 繼續 如果 > [帶var] > 在當前作用於中聲明了一個變量,如果當前是全局作用域,也相當於給全局作用域設置了一個屬性叫做a ```javascript //=>變量提升:var a; &l