国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js作用域和this的理解

李文鵬 / 2922人閱讀

摘要:總結總而言之,作用域在語法分析時就已經處理完啦,的作用域是靜態作用域,在運行時只是上下文對象在一直發生變化。

JavaScript 的作用域和上下文對象this

從幾個有意思的js問題開始

為什么輸出的不是f2?

`var scope = "top";
  var f1 = function() { 
      console.log(scope);
  };
  f1(); // 輸出 top
  var f2 = function() { 
      var scope = "f2"; 
      f1();
  };
   f2(); // 輸出 top`

我還能訪問closure,但this值改變

`function closure(arg){
     var a ="closure";
     console.log(a);//(1) closure
     console.log(this);//(2) obj對象
     return function(){
            console.log(a);//(4) closure
            console.log(arg); // (5) arg
            console.log(this);//(6) windowd對象
          }
     }
 var obj ={
    func:closure
    }
 function func () {
    setTimeout(obj.func("arg"),100);
    console.log("funcEnd");// (3)funcEnd
    }
 func()`

this會被綁定在某個對象上

`var b = "window.b"
 var funcFactory = function(){
    var b ="func.b";
    var obj ={
        a:"obj.a",
        func:function(){
            console.log(b)
            console.log(this.a);
        }
    }
    return obj;
 }
 var temp =funcFactory()
    var func = temp.func;
    temp.func();// 先出現 func.b 后出現obj.a
    func();// 先出現func.b 后出現 undefined`

4.函數執行完了,this綁定在window上

`function func(){
    var a=1;
    setTimeout(function(){
        console.log(a)
    },100);
  }
  func();// 1`

深度理解js靜態作用域

js靜態作用域

在第一段代碼中很多人會理所當然的認為會打印出f2來,會說f2是個function,js是個以function為作用域劃分,然而事情往往事與愿違---最后打印出的是出乎意料的top。人人都知道js在執行之前會進行預處理(V8處理js還會先把它編程字節碼),很多人只知道在預處理的時候會出現var變量的提升(es6的let就不會啦)和function一等公民的預先處理。然而卻忽略了作用域的處理--- 函數作用域的嵌套關系是定義時決定的,而不是調用時決定的,也就 是說,JavaScript 的作用域是靜態作用域,又叫詞法作用域,這是因為作用域的嵌套關系可 以在語法分析時確定,而不必等到運行時確定。

this與作用域的誰在變化

首先讓我們來理解下scope的概念---一段程序代碼中所用到的名字并不總是有效/可用的,而限定這個名字的可用性的代碼范圍就是這個名字的作用域。在網上總是有什么前端面試題問setTimeout或者setInterval里面的變量為什么會改變,給出的答案永遠是千篇一律的作用域發生了變化,然而我們從第一段代碼中我們就知道js是一個在語法分析時作用域就已經確定了的。那到底是什么發生了變化了呢?是this(學名上下文對象),this這個值在js中是很詭異的,等我有時間專門要拿出來講一講,this這個值是會在運行時動態的發生變化的,比如call,apply,bind。至于setTimeout和setInterval一對兄弟,我想再分享一段代碼來解釋下

 function func(){
    var a=1;
    setTimeout(function(){
        console.log(a)
    },100);
    while(true){
        a=2;
    }
}
func();

四段代碼中你可以看見1,但在這段代碼中你永遠也不會再控制臺上發現1 的影子,因為只要沒執行完func這個函數,js永遠不會去事件隊列里面查詢是否有事件發生。同時js的變量回收也是在執行完一個函數后才執行的。

this和作用域的匯總介紹

第三段代碼的匯總使用啦,temp會從function中發揮obj對象,在我們調用temp.func的時候,this值會被綁定在obj這個對象上,顯示console.log(b),因為b是從作用域中拿到的,所以在語法分析時就已經給設定好啦,所以在控制臺上打印出“func.b”,在調用this.a時,因為this被運行時綁定在obj對象上,所以會直接在obj上找(如果對象沒有可以繼續向上找原形鏈),當變量func去得到obj.func時,他只得到的是函數(不帶包含它的對象),this自動會綁在window上,所以只能打印出b來(在語法分析時就已經注定了訪問哪個變量),所以在window上找不到a這個屬性,就導致了undefined的出現。

總結

總而言之,作用域在語法分析時就已經處理完啦,JavaScript 的作用域是靜態作用域,在運行時只是this(上下文對象)在一直發生變化。也就是一個在運行前就完成劃分(詞法作用域Lexical Scope),一個是在運行中改變(類似于動態作用域Dynamic Scope),嚴格意義上說JavaScript只是詞法作用域。

js只有function來劃分作用域。this的改變方式就大概有三種,第一種call,apply,bind方法(有點類似于c++的組合型配接器)this會被綁定在第一個參數對象,第二種事件方法,setTimeout和setInterval會被綁定在全局對象上,像點擊事件之類的會被綁定在dom對象上,第三種obj.func訪問對象里的function會被綁定在最里面的對象上,例如obj1.obj2.obj3.func會綁定在obj3上(有人會說function里面也可以寫this的屬性,對呀function也是繼承自Object的呀,它自己本身就帶上下文對象的)

作用域可以訪問嵌套它的作用域值,而this是按著原形鏈去訪問它父級對象,注意啦就如上例obj1.obj2.obj3.func,obj3雖然是obj2的屬性,但不是繼承于obj2的,它繼承是通過它prototype屬性來繼承的,所以在obj3.func中this并不會去訪問obj2的屬性

后記

不希望以后有人會拿以上代碼來面試或以以上代碼去面試企業,這些知識知道就好了,實戰能力和對業務的把控才是程序猿技術的關鍵。

[1](http://www.cnblogs.com/bennman/archive/2013/09/08/3309024.html)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/78886.html

相關文章

  • 深入理解JavaScript作用域和作用域鏈

    前言 JavaScript中有一個被稱為作用域(Scope)的特性。雖然對于許多新手開發者來說,作用域的概念并不是很容易理解,本文我會盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲! 想閱讀更多優質文章請猛戳GitHub博客 作用域(Scope) 1.什么是作用域 作用域是在運行時代碼中的某些特定部分中變量,函數和對象的可訪問性。換句話說,作用域決定了代碼區塊中變量和其他資源的可見...

    baiy 評論0 收藏0
  • 深入理解JavaScript作用域和作用域鏈

    前言 JavaScript中有一個被稱為作用域(Scope)的特性。雖然對于許多新手開發者來說,作用域的概念并不是很容易理解,本文我會盡我所能用最簡單的方式來解釋作用域和作用域鏈,希望大家有所收獲! 想閱讀更多優質文章請猛戳GitHub博客 作用域(Scope) 1.什么是作用域 作用域是在運行時代碼中的某些特定部分中變量,函數和對象的可訪問性。換句話說,作用域決定了代碼區塊中變量和其他資源的可見...

    ytwman 評論0 收藏0
  • JS基礎】作用域和閉包

    摘要:變量提升的理解語言的執行規則先定義,后執行變量定義函數聲明就屬于定義代碼的范疇注意函數聲明和函數表達式的區別說明幾種不同的使用場景要在執行時才能確認值,定義時無法確認全局環境下的對象方法中的構造函數中的事件函數中的觸發當前事件的對象中的創建 變量提升的理解 js語言的執行規則:先定義,后執行變量定義、函數聲明就屬于定義代碼的范疇(注意函數聲明和函數表達式的區別) 說明this幾種不同的...

    SolomonXie 評論0 收藏0
  • 理解JavaScript中作用域和作用域鏈

    摘要:示例當一個函數創建后,它的作用域鏈會被創建此函數的作用域中可訪問的數據對象填充。每一個運行期上下文都和一個作用域鏈關聯。此時,作用域鏈中函數的所有局部變量所在的作用域對象會被推后,訪問代價變高了。 作用域 作用域就是變量與函數的可訪問范圍,即作用域控制著變量與函數的可見性和生命周期。在JavaScript中,變量的作用域有全局作用域和局部作用域兩種。 作用域鏈 函數對象有一個內部屬性[...

    XanaHopper 評論0 收藏0
  • javascript作用域和閉包之我見

    摘要:查詢是在作用域鏈中,一級級的往上查找該變量的引用。作用域和作用域鏈作用域的概念,應該兩張圖幾句話就能解釋吧。這個建筑代表程序中的嵌套作用域鏈。一層嵌一層的作用域形成了作用域鏈,變量在作用域鏈中的函數內得到了自己的定義。 javascript作用域和閉包之我見 看了《你不知道的JavaScript(上卷)》的第一部分——作用域和閉包,感受頗深,遂寫一篇讀書筆記加深印象。路過的大牛歡迎指點...

    SoapEye 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<