Javascript中this的認真理解

Javascript中的this,是每個FE都需要花費一段時間要去認真理解的的東西。this具體指的是什麼?
this
在javascript語言中,凡是發生函數調用的地方,都會產生this。像在Java中,如果有this,那麼它一定是代表其所在的對象。但是Javascript中函數調用多種多樣,不同的調用方法,this也將會指代不同的東西。我們先來分析一下函數的調用方式,據我使用過的有這麼四種方式:
1 作爲函數調用,函數嘛,肯定是會以函數的方式進行調用的,在這種情況下,this將會指向全局,即window對象

    this.x = 0;
    function foo(){
        console.log(this.x);
    }
    foo();//0

嵌套的函數調用:

    this.x = 0;
    function foo(){
        console.log(this.x);
        function bar(){
            console.log(this.x);    
        }
        bar();
    }
    foo();//0 0

對象下的函數調用:

    this.x = 3;

      var o = {
        x:5,
        m:function(){
          console.log(this.x);

          function foo(){
            console.log(this.x);
          }
          foo();
        }
      };
      o.m();//5 3

無論嵌套多深,函數調用的this都會指向window。

2 作爲對象的成員方法,此時this自然指向這個對象了。

    var obj = {
        name:'zhangsan',
        say:function(){
          console.log(this.name);
        }
      };
    obj.say();// zhangsan
    function foo(){
        console.log(this.name);
      }

      var obj = {
        name:'zhangsan',
        say:foo
      };
      obj.say();//zhangsan
    var foo = {
        name:'lisi',
        say:function(){
          console.log(this.name);
        }
      };

      var obj = {
        name:'zhangsan',
        say:foo.say
      };
      obj.say();//仍然打印 zhangsan

雖然成員方法有時不是直接寫在對象下面的,但是如果最後還是這個對象調用了這個方法,那麼this仍然指向這個對象。

3 new 出的對象中,this一般指向該對象。這個用法和Java中的類似,在構造函數中使用this,將指向new創建的新對象上。在此就不直接舉例了。

4 call(),apply(),bind()方法,這三個方法,在我的一篇博客中明確的解釋了他們的用法:關於call,apply,bind方法的理解,他們是用來改變函數中的this指向的,這裏也不進行舉例了,不明白的話,可以看一看我那篇文章。

其實,說到頭來,還是對javascript的原理不太瞭解,所以纔對this 不好掌握,我在知乎上看到一篇文章:這裏寫鏈接內容,這裏面就明確寫到了this該怎麼理解。

他寫道,直接函數調用和對象成員方法的調用都是javascript中的語法糖,真正所有的方法的調用都是使用call()來調用的。

    fun.call(context,arg1,arg2...);

在這裏的context就是函數運行的上下文,也就是this對象了,
直接函數調用其實可以寫成這樣:

    fun();
    /*寫成這樣:*/
    fun.call(undefined);

    obj.fun();
    /*寫成這樣:*/
    obj.fun.call(obj);

所以,在javascript中,我們自始至終只有一種函數調用方式:那就是:

    fun.call(context,arg1,arg2);

從我那篇文章中可以知道,當context爲undefined時,上下文就會指向windows.因此:

      this.x  = 1;
        function foo(){
          console.log(this.x);
        }

        foo();//1
        foo.call(undefined);//1

    var obj = {
        name:'zhangsan',
        say:function(){
          console.log(this.name);
        }
      }
      obj.say();//1
      obj.say.call(obj);//1

有一個例子:

    var foo = {
        name:'lisi',
        say:function(){
          console.log(this.name);
        }
      };

      var obj = {
        name:'zhangsan',
        say:foo.say
      };
      obj.say();//仍然打印 zhangsan

這裏say:foo.say,我們知道函數也是一個對象,所以,這裏只是一個引用的傳遞,所以這裏obj.say()調用的只是這個方法,跟foo這個對象並沒有任何關聯。

感謝:這裏寫鏈接內容

發佈了32 篇原創文章 · 獲贊 6 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章