JavaScript
中的this
this
爲什麼如此多變?node
this老是跟它的執行上下文有關,而在JavaScript總會有開闢新的執行上下文的東西,好比函數,因此,this才如此的變化。
執行環境對
JavaScript
中的this
有影響嗎?瀏覽器
JavaScript是一門解釋型語言,須要有一個執行環境去執行它,一般的執行環境是瀏覽器,還有node腳本,還有`REPL`(「讀取-求值-輸出」循環(Read-Eval-Print Loop,簡稱REPL))。 若是對REPL有興趣的話,博客中的另外一篇文章介紹了`REPL`
this
默認指代誰?安全
在不一樣的執行環境中,會指代不一樣的對象
瀏覽器中:函數
> this // Window {top: Window, window: Window,... > this === window //true > var a = 1; //在全局中,用var聲明變量,會默認給window添加 > this.a // 1 > window.a // 1 > b = 1; //不使用var聲明變量,會默認給全局的this添加屬性 > this.b // 1 > window.b // 1
在node
腳本中oop
console.log(this); //{} console.log(this === global); //false console.log(this === window); //ReferenceError: window is not defined var a = 1; //在全局中,使用var聲明變量,未給global添加屬性 console.log(this.a); //undefined console.log(global.a); //undefined console.log(window.a); //ReferenceError: window is not defined b = 1; //不使用var聲明變量,會默認給全局的global添加屬性。 console.log(this.b); //undefined console.log(global.b); // 1 在node腳本中,this默認指向一個空對象,並非指向global,也不是指向window。
在REPL
中this
> this { DTRACE_NET_SERVER_CONNECTION: [Function], DTRACE_NET_STREAM_END: [Function], ... > global === this //true > var a = 1; //在全局中,使用var聲明變量,會默認給全局的global添加屬性 > this.a // 1 > global.a // 1 > b = 1; //不使用var聲明變量,會默認給全局的this添加屬性 > this.b // 1 > global.b // 1
咱們對於省略
var
的變量聲明方式,咱們總說它是不安全的,可是是合法的。code
爲何不安全?對象
如上文所述:不使用var聲明變量,會讓變量默認的添加到了全局的this中,這有時候會莫名的給變量提高它的做用域,從而影響其餘全局變量。
舉個栗子:ip
var position = "outer"; //this.position = "outer" function test(){ position = "inner"; //this.position = "inner",在函數執行後,覆蓋原先的值 console.log(this.position); } test();
咱們在外部定義了一個名爲position
的全局變量,它會被默認添加到全局this的屬性上。作用域
而後在咱們的test
函數中,又定義了一個同名的變量,可是注意,函數中的變量聲明沒有用var
。
由於咱們並無對函數實例化,因此this.position
的this
會默認指代全局。
而當咱們調用函數test
時,函數會生成一個執行上下文,而內部position
會將做用域從函數內部提高到全局,從而覆蓋(污染)了外部全局定義的position
變量。
因此,在JavaScript
的嚴格模式中,是不容許省略var
來聲明變量的。故在聲明變量的時候,就順手加上var
吧。
this
在不一樣的執行環境中的默認指代var
聲明變量致使「變量提高」現象的發生及預防