JavaScript[14] -- this

總結:

方法自執行時,this指向window,被對象調用時,this指向對象。
能夠用call(),apply()和bind()改變this指向。

默認綁定

  • 全局環境中this默認綁定到windowjson

    <script>       
        console.log(this);        //window        
    </script>
  • 函數獨立調用,this默認綁定到window數組

    <script>       
        function func(){
            console.log(this);     //window
        };
        func();
    </script>
  • 被嵌套的函數獨立調用,this默認綁定到window閉包

    <script>
        var a = 0;    // Window中的a
        
        var obj = {
             a : 1,    // obj中的a
             func : function(){
                 var a = 2         // func中的a
                 function test(){
                     var a = 3;    // test中的a
                     console.log(this.a)       // this指向Window
                 };
                 test();
             }
         };
         
         obj.func();
    </script>
  • 閉包中函數獨立調用,而不是方法調用,this默認綁定到windowapp

    <script>
        var a = 0;    // Window中的a
        
        function func(){
             var a = 1;        // func中的a
             function test(){
                 var a = 3;    // test中的a
                console.log(this.a);      //this指向Window
            }
            return test();
        };
         
        func();
    </script>

隱式綁定

  • 通常被直接對象包含的函數調用時,也叫方法調用,this存在隱式的綁定到該對象函數

    <script> 
        var a = 0;
    
        function func(){
            console.log(this.a);
        };
    
        var obj1 = {
            a : 1,
            func : func,
            obj2 : {
                a : 2,
                func : func,
            },
        };
    
        obj1.func();            // 1
        obj1.obj2.func();       // 2
    
    </script>

隱式丟失

  • 隱式丟失是指被隱式綁定的函數丟失綁定對象,從而默認綁定到windowthis

    <script>
           var a = 0;
       
           function func(){
               console.log(this.a);
           };
       
           var obj1 = {
               a : 1,
               func : func,
               obj2 : {
                   a : 2,
                   func : func,
               },
           };
       
           obj1.func();   // 1 這是一個對象下的方法隱式綁定,因此對象是obj1
           
           var bar = obj1.func;    // 把obj1.func賦值給bar變量,形成隱式丟失,由於這個變量和對象obj1毫無關係
           bar();         // 0
       </script>
  • 函數在做爲一個參數傳遞的時候,會隱式丟失,this默認指向Windowcode

    <script>
           var a = 0;
    
           function func(){
               console.log(this.a);
           };
    
           function bar(fn){
               fn();
           };
    
           var obj = {
               a : 1,
               func : func,           
           };
    
           obj.func();    // 1 這是一個對象下的方法隱式綁定,因此對象是obj1
           
          
           bar(obj.func);  // 0 把函數做爲參數傳遞,會形成隱式丟失
    
       </script>

嚴格模式

  • 開啓嚴格模式: "use strict",避免未聲明變量泄露對象

    <script> 
           
       "use strict"    // 開啓嚴格模式
    
       a = 0;          // a會泄露到Window中
       
       console.log(this.a);        // 嚴格模式開啓,此處結果爲0; 嚴格模式未開啓,此處結果爲 a is not defined    
       
    </script>

改變this指向(顯式綁定)

  • call() 會自執行事件

    1.當call()不傳遞參數的時候,this默認指向window
    2.當call()傳遞參數時,,第一個參數必須指向某一個對象,後面的參數是實參ip

    <div id="box">box</div> 
           
       <script>
           let a = 1;
           let b = 2;  
       
           let json = {
               a : 3,
               b : 4,
           };
           
           function func(){
               console.log(this.a + this.b)  // 此處this的指向根據調用方不一樣,指向不一樣的地方  
           }
       
           func(); // NaN 由於let不會泄露到Window,因此this指向的Window中沒有a和b
       
           let box = document.getElementById("box");   // 獲取box對象
           box.a = 10;     // 設置box對象屬性a的值爲10
           box.b = 20;     // 設置box對象屬性b的值爲20
           
           // box.onclick = func; // 30 設置box對象onclick事件,點擊box對象,this指向box對象,得到結果爲30
           
           // box.onclick = func.call(); // NaN   當call()不傳遞參數的時候,this默認指向window
           
           box.onclick = func.call(json);  // 7     當call()傳遞參數時,,第一個參數必須指向某一個對象,後面的參數是實參
       </script>
  • apply() 會自執行
    1.接收兩個參數,第一個是指向的某一個對象,第二個必須是一個數組,數組裏面是函數須要的實參

    <script>
        let a = 1;
        let b = 2; 
    
        let json = {
            a : 3,
            b : 4,
        };
    
        function func(a, b){
            console.log(this.a + this.b);
            console.log(a + b)
        }
      
        func.apply(window, [3,3]);  // NaN 6    第一個是指向的某一個對象,第二個必須是一個數組,數組裏面是函數須要的實參
        func.apply(json, [3,3]);    // 7 6    第一個是指向的某一個對象,第二個必須是一個數組,數組裏面是函數須要的實參
       
    </script>
  • bind() 不會自執行

    <div id="box">box</div>
    
    <script>
        let box = document.getElementById("box");   // 獲取box對象
        let json = {
            a : 3,
            b : 4,
        }
        function func(a, b){
            console.log(this.a + this.b);
            console.log(a + b);
        }
    
        box.onclick = func.bind(json, 3, 3);  // 7 6 點擊box對象後執行函數,無參數指向Window
    </script>

小技巧

  • 點擊一個對象時,使用另外一個對象的屬性

    <div id="box1">box</div>
    <div id="box2">box2</div>
    
    <script>
        let box1 = document.getElementById("box1");   // 獲取box1對象
        box1.a = 1;
        box1.b = 2;
           
        let box2 = document.getElementById("box2");   // 獲取box2對象
        box2.a = 3;
        box2.b = 4;
    
        function func(){
            console.log(this.a + this.b);           
        }
    
        box1.onclick = func.bind(box2);  // 7 點擊box1時,使用box2的屬性
    </script>
相關文章
相關標籤/搜索