This 指針--深思

今天早上看到公衆號推送了阮一峯老師的文章JavaScript 的 this 原理,文章不是很長因而研究了一下。javascript

看完本身的總結以下:html

this

  • this 指向函數運行時所在的環境。
  • 函數運行在對象內,this 就指向該對象
  • 運行在全局環境,this 就指向全局環境
  • js 容許函數體內部引用當前環境外的其餘變量,因爲函數能夠在不一樣運行環境執行,「當前環境外的其餘變量」就是指「不一樣運行環境中的變量」 ,那麼這個時候就須要有一種機制,可以在函數體內部得到當前的運行環境,因此 ==this== 就應運而生了。

看到 ==js 容許函數體內部引用當前環境外的其餘變量== 想到以前本身總結過的關於做用域的知識點:java

做用域

  • 函數定義的時候就被肯定了做用域,與它在什麼地方被調用執行無關
  • 當前做用域沒有定義的變量,即自由變量,會到父級做用域中查找,和執行做用域無關;

令我產生困惑的兩句話:node

  • 函數定義的時候就被肯定了做用域,和執行做用域無關
  • js 容許函數體內部引用當前環境外的其餘變量

這裏的 ==執行做用域== 與下文的 ==當前環境外的其餘變量== 如何理解或者作區分?瀏覽器

翻閱紅寶書(第三版)p73,執行環境是 js 中最爲重要的一個概念,總結以下:模塊化

  1. 函數的運行環境即其執行環境
  2. 每一個函數都有本身的執行環境,執行環境定義了函數有權訪問的其餘數據,保存在變量對象之中。
  3. 當代碼在一個環境中執行時,會建立變量對象的一個做用域鏈。做用域鏈決定了訪問變量對象的順序。
  4. this 能夠指向不一樣的運行環境,這裏的運行環境本質上指的是對象,能夠是內建對象、自定義對象或者全局對象。
  5. 函數定義時就被肯定了做用域,這個做用域決定了其訪問變量對象的順序。而函數能夠在不一樣環境被執行,這裏的 ==不一樣環境== (多是外層函數或者全局環境下)的做用域纔是執行做用域。
  6. 因此 執行做用域 能夠理解爲 函數執行位置外部函數或者全局環境的做用域, 與函數本身的做用域(聲明時就被肯定了) 徹底是兩碼事
  7. 當前環境外的其餘變量即函數本身做用域外的其餘變量
  8. 函數要想引用 當前環境外的其餘變量 只能用 this ,this 指向當前運行環境,運行在對象內就指向對象,運行在全局環境就指向全局對象
  9. 咦,我本身怎麼也有點亂。。

運行在全局環境的 this

衆所周知,瀏覽器環境下 全局環境下的 this 就是 window,沒有一點問題函數

// 瀏覽器環境下
var a = 'a'
this.b = 'b'
console.log(this.a)  // a
console.log(b)      // b
console.log(this===window) // true

可是...

// node 環境下
var x = 'xx'
global.y = 'yy'
// node 環境下輸出
console.log(y);   // yy  global 屬性掛載到了全局環境, 
console.log(global.x) // undefined   全局環境中定義的x 變量並無掛載到頂層對象global對象中
console.log(this === global)  // false 
console.log(JSON.stringify(this))// {}  空對象,並非 global

查閱MDN發現:this

// node 環境下
function f1() {
    return this
}

console.log(f1() === global) // true  
console.log(this === global) // false

node 環境下只有定義在函數內部的 this 才指向 global ?
那麼, node 環境下 this 到底指向什麼?通過和導師的溝通
終於發現設計

// node 環境下
this.num = '10'
global.test = '12'
console.log(module.exports) // {num: "10"}    
console.log(this===module.exports) // true

那麼 node 環境下 this 爲何指向 module.exports 這和模塊化的設計又有什麼關係?code

發人深思...

天色已晚,且聽下回分解。

相關文章
相關標籤/搜索