首頁  >  文章  >  web前端  >  Javascript中關於this關鍵字指向問題的測試詳解

Javascript中關於this關鍵字指向問題的測試詳解

黄舟
黄舟原創
2017-08-11 10:34:581301瀏覽

this是Javascript中一個非常容易理解錯,進而用錯的特性。所以下面這篇文章主要給大家介紹了關於Javascript中this關鍵字指向問題的相關資料,文中通過測試的題目考驗大家對this的熟悉程度,需要的朋友可以參考借鑒,下面來一起看看吧。

前言

Javascript是基於物件的動態語言,也就是說,所有東西都是對象,一個很典型的例子就是函數也被視為普通的物件。 Javascript可以透過一定的設計模式來實現物件導向的編程,其中this 「指標」就是實現物件導向的一個很重要的特性。本文將給大家詳細介紹關於Javascript中this關鍵字指向的相關內容,讓我們先做一個小測試,如果全部答對了,恭喜你不用往下看了。

測驗題目

#第一題


<script>
 var str = &#39;zhangsan&#39;;

 function demo() {
  var str = &#39;lisi&#39;;
  alert(this.str);
 }
 window.demo(); // ??

 var obj = {
  str: "wangwu",
  say: function() {
   alert(this.str);
  }
 }
 obj.say(); // ??

 var fun = obj.say;
 window.fun(); // ??
</script>

第二題


#
<script>
 var username = &#39;zhangsan&#39;;

 (function() {
  var username = &#39;lisi&#39;;
  alert(this.username); // ??
 })()

 function demo() {
  var username = &#39;wangwu&#39;;

  function test() {
   alert(this.username);
  }

  test(); // ??
 }
 demo();
</script>

#第三題


<script>
 function Person() {
  this.username = &#39;zhangsan&#39;;
  this.say = function() {
   alert(&#39;我叫&#39; + this.username);
  }
 }

 var p = new Person();
 p.say(); // ??

 var p1 = new Person();
 p1.say(); // ??
</script>

第四題


#
<script>
 var username = &#39;zhangsan&#39;;

 function demo() {
  alert(this.username)
 }

 var obj1 = {
  username: "lisi"
 };
 var obj2 = {
  username: "wangwu"
 };

 demo(); // ??
 demo(obj1); // ??
 demo(obj2); // ??
 demo.call(obj1); // ?? 
 demo.apply(obj2); // ??
</script>


  • ##第一題:zhangsan wangwu zhangsan
  • 第二題:zhangsan zhangsan
  • 第三題:我叫zhangsan 我叫zhangsan


#第四題:zhangsan zhangsan zhangsan lisi wangwu

#(往下看,下面有詳細解析哦)

  • this

  • #this

  • 指向呼叫函數的物件

無物件呼叫函數/匿名函數自呼叫(this指向window)


透過new產生的物件

  • apply/call呼叫

  • 一、指向呼叫函數的物件
  • <script>
     // this:指向调用函数的对象
     var str = &#39;zhangsan&#39;;
    
     function demo() {
      var str = &#39;lisi&#39;;
    
      //this->window
      console.log(this);
      alert(this.str);
     }
     window.demo(); // zhangsan
    
     var obj = {
      str: "wangwu",
      say: function() {
       // this->obj
       alert(this.str);
      }
     }
     obj.say(); // wangwu
    
     var fun = obj.say;
     window.fun(); // zhangsan
    </script>

  • 全域函數(demo)屬於window物件的方法,window呼叫demo所以this就指向了window

obj呼叫say方法,this就指向了obj


fun()是全域函數,而宣告的fun接收的是obj裡面單純的一個函數,並沒有呼叫(obj.say()才是呼叫了函數),此時的fun就是一個函數(function(){alert(this.str);}),那麼當fun()呼叫函數的時候,this指向的就是window

  • 是誰呼叫的函數,那麼this就指向誰

  • 二、無物件呼叫函數/匿名函數自呼叫->this指向window


#

<script>
 // 2.匿名函数自执行|匿名函数|无主函数 this->window
 var username = &#39;zhangsan&#39;;

 // 匿名函数自执行 this->window
 (function() {
  var username = &#39;lisi&#39;;
  console.log(this); // window
  alert(this.username); // zhangsan
 })()

 function demo() {
  var username = &#39;wangwu&#39;;

  // 无主函数 this->window
  function test() {
   // this->window
   alert(this.username);
  }

  test(); // zhangsan
 }
 demo();
</script>


因為匿名函數沒有名字,所以就掛給window了

  • test(),誰呼叫test那麼就指向誰。當然實驗過,它不是window調用的,也不是demo調用的,沒有人管它,那麼它就指向window。它就相當於一個沒有主人呼叫它,無主函數。

三、透過new產生的物件

<script>
 // 3.通过new的对象:this指向产生的对象
 // 函数
 function Person() {
  // 属性
  this.username = &#39;zhangsan&#39;;
  // 方法
  this.say = function() {
   // this->p
   console.log(this); // Person对象
   alert(&#39;我叫&#39; + this.username);
  }
 }

 // 实例化出一个对象:p就具有了username属性和say方法
 var p = new Person();
 console.log(p); // Person对象
 console.log(p.username); // zhangsan
 p.say(); // 我叫zhangsan

 // this->p1
 var p1 = new Person();
 p1.say(); // Person对象 我叫zhangsan
</script>


當我們的函數Person裡面運用了this去寫屬性和方法這種格式,那麼就要透過new來讓屬性和方法變得有價值,透過new去運用函數裡面的屬性和方法


#四、apply/call呼叫

首先我們來了解下apply()/call()是個什麼東西呢?

apply()/call():最終是呼叫function,只不過內部的this指向了thisObj


function.call([thisObj[,arg1[, arg2[, [,.argN]]]]])
function.apply([thisObj[,argArray]])

#注意:


1. 呼叫function函數,但是函數內的this指向thisObj(更改物件內部指標)


2. 如果thisObj沒有傳參,則預設為全域物件


3. call()/apply()連結與差異

    連結:功能一樣,第一個參數都是thisObj


    差異:傳遞的參數若比較多

        call()的實參就是一一列出

##        apply(


##      參是全部放置在第二個陣列參數中

  • 一個理解apply()/call()的實例:

  • ##

    <script>
     // apply()/call()
     function demo() {
      console.log(123);
     }
    
     // 调用函数的时候,demo.call()/demo.apply()最终调用的还是demo()
     demo(); // 123
     demo.call(); //123
     demo.apply(); // 123
    </script>
    
    <script>
     // call()/apply()的区别:
     // call()参数单独再call中罗列
     // apply()的参数通过数组表示
     function demo(m, n, a, b) {
      alert(m + n + a + b);
     }
     demo(1, 5, 3, 4); // 13
     demo.call(null, 1, 5, 3, 4); // 13
     demo.apply(null, [1, 5, 3, 4]); // 13
    </script>

  • this的第四個用法實例

<script>
 // this的第四个用法:call(obj)/apply(obj):强制性的将this指向了obj
 var username = &#39;zhangsan&#39;;

 function demo() {
  alert(this.username)
 }

 var obj1 = {
  username: "lisi"
 };
 var obj2 = {
  username: "wangwu"
 };

 // call()/apply():打劫式的改变了this的指向
 demo(); // zhangsan
 demo(obj1); //zhangsan
 demo(obj2); //zhangsan
 demo.call(obj1); // lisi 
 demo.apply(obj2); // wangwu
</script>

###如果直接呼叫demo裡面寫的不管是obj1還是obj2,那麼demo還是屬於window呼叫的。 ############不管你用call或apply最終呼叫的都是demo函數,但它們會強制的this指向了obj1/obj2,強制的指向了它們的第一個參數物件。 ##################總結##########

以上是Javascript中關於this關鍵字指向問題的測試詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn