JavaScript中的this

1:基本概念

this字面意思是當前,當前執行代碼的環境對象或者是上下文。表明着當前方法執行的環境上下文,那麼何爲環境上下文,通俗的說,誰調用了函數,誰就是這個函數的環境上下文。瀏覽器

在js中,this只有兩種指向,一種是指向當前的封閉做用域,或者是指向當前做用域的外層,this的最頂層就是window對象。app

關於this必需要了解的是嚴格模式,嚴格模式是js裏面的一個子集,是具備限制性JavaScript變體,嚴格模式也是js的一種,可是加了一些限制。函數

好比:優化

  • 在嚴格模式下經過拋出錯誤來消除了一些原有的靜默錯誤(靜默錯誤:語法有錯誤可是js並無提示,默認容許這個操做)。好比要取一個函數的傳入參數,在非嚴格模式下,能夠直接拿到它的grument,但在嚴格模式下會拋出一個錯誤。
  • 嚴格模式修復了一些致使JavaScript引擎難以執行優化的缺陷
  • 禁用了在ECMAScript的將來版本中可能會定義的一些語法

進入"嚴格模式"的標誌:"use strict";this

// 爲整個腳本開啓嚴格模式 
    "use strict";
    var v = "Hi!  I'm a strict mode script!";
    
    // 爲函數開啓嚴格模式 
    function strict() {
        'use strict';
        function nested() { 
            return "And so am I!"; 
        }
        return "Hi!  I'm a strict mode function!  " + nested();
    }

2:全局環境

在全局環境下,不管是否在嚴格模式下,在全局執行環境下(任何函數體外部)this指向全局對象。也就是說在全局執行環境,這個this永遠指向全局對象,這個全局對象在瀏覽器中就是window。code

//瀏覽器環境
    var name = 'Eric';
    console.log(window.name === this.name);  /* true */
    console.log(window === this);            /* true */

3:函數體內部

在函數體內部,this的值取決於函數被調用的方式。函數被調用的方式有不少種:對象

簡單調用,也就是說沒有添加任何額外的操做,沒有添加一個this的綁定或者是改變。遞歸

簡單調用分爲嚴格模式與非嚴格模式。ip

  • 在非嚴格模式下,this默認指向全局對象。
    // 瀏覽器環境
      function simple(){
          return this;
      }
      console.log(simple() === window);
      // true
  • 在嚴格模式下,保持進入執行環境時的值,沒有指定時默認undefined。
    // 瀏覽器環境
       function simple2(){
           "use strict";
           return this;
       }
       simple2() === undefined;
       // true 
       window.simple2() === window;
       // true

this傳遞,在js中this綁定有兩種:作用域

  • 一種是call/apply,能夠看做是一種,它們都是一個綁定this的當即執行的一個方法,綁定以後會當即執行這個函數,二者的區別在於傳遞參數的不一樣,一個是傳一個參數,一個是傳一堆參數;call/apply其實是綁定值的是一個對象,存在一個ToObject過程。call/apply是一個當即執行的綁定this的一個操做。
    // 瀏覽器環境 
       var object = {
           name: 'Eric'
       };
       var name = 'Iven';
       function getName(arg) {
           return this.name;
       }
    
       getName(); /* Iven */
       getName.call(object); /* Eric */
       getName.apply(object); /* Eric */
  • 另外一種是bind,與上面不一樣的是bind不會當即執行,它只是實現一個綁定的過程,返回的是一個柯里化的函數,這個柯里化的函數就是call/apply。bind只能被綁定一次。
    name = 'Davy';
       function bindThis(){
           return this.name;
       }
       var getName1 = bindThis.bind({ name: "Eric" });
       console.log(getName1()); /* Eric */
    
       var getName2 = getName1.bind({ name: "Iven" });
       console.log(getName2()); /* Eric */

箭頭函數在執行的時候會造成一個封閉的做用域,this與封閉做用域的this保持一致,call/apply/bind都將會被忽略。

// 瀏覽器環境 
 var globalThis = this;
 var arrowsFunction = () => this;
 console.log(arrowsFunction() === globalObject); /* true */

做爲對象的方法被調用(有一個靠近原則):在對象裏面定義了一個函數,而後經過對象去調用這個函數。

// 瀏覽器環境 
 var object = {
     name: 'Eric',
 
     getName: function() {
         return this.name;
     }
 };
 console.log(object.getName()); /* Eric */
 
 
 function getName2() {
     return this.name;
 }
 object.getName = getName2;
 console.log(object.getName()); /* Eric */
 
 
 object.object = {
     getName: getName2,
     name: 'Iven'
 };
 console.log(object.object.getName()); /* Iven */

4:全局函數

  • setTimeout
  • setInterval
  • alert

setInterval()方法用於在指定的毫秒數後調用函數或計算表達式。

語法:setTimeout(code,millisec),參數code必需,要調用的函數後執行的JavaScript代碼串;millisec必需,在執行代碼前等待的毫秒數。

注意:setTimeout()只執行code一次,若是須要屢次調用,請使用setInterval()或者讓code自身再次調用setTimeout(),也就是利用遞歸。

setInterval()方法可按照指定的週期來調用函數或計算表達式。它會不停地調用函數,指導clearInterval()被調用或者窗口被關閉。由setInterval()返回的ID值能夠用做clearInterval()方法的參數。

語法:setInterval(code,millisec[,"lang"])

相關文章
相關標籤/搜索