this關鍵字詳解

關於this的綁定

默認綁定 this 默認 綁定到 windows

  1. 在全局環境中,this默認綁定到 windows
  2. 函數獨立調用時,this默認綁定到 windows
  3. 被嵌套函數獨立調用時, this 默認綁定到 windows
  4. IIFE 當即執行函數, 其實是函數申明以後當即調用
  5. 閉包函數, 是獨立調用,而不是方法調用。javascript

    var a = true;
        function fun(){
            function test(){
                console.log(a)
            }
            return test;
        }
    
        var o = {
            a : false;
            fun : fun;
        }
    
        o.fun()(); // true

    因爲閉包的this默認綁定到window對象,但又經常須要訪問嵌套函數的this,因此經常在嵌套函數中使用var that = this,而後在閉包中使用that替代this,使用做用域查找的方法來找到嵌套函數的this值java

    var a = true;
        function fun(){
            var that = this; //  用來記錄 fun 的 this 
            function test(){
                console.log(that.a)
            }
            return test;
        }
    
        var o = {
            a : false;
            fun : fun;
        }
        o.fun()(); // false

隱式綁定

在方法調用時(被對象包含的函數,被對象直接調用時),this隱式的 綁定到該對象上。

```
    var a = 0;
    function fun(){
        console.log(this.a)
    }

    var o = {
        a : 1;
        fun : fun;
    }
    o.fun() // 1

```

當對象嵌套時,依然是直接對象

```
    var a = 0;
    function fun(){
        console.log(this.a)
    }
    var o1 = {
        a : 1;
        fun : fun;
        o2:{
            a : 2;
            fun : fun;
        }
    }
    // fun函數的直接對象o1
    o1.fun() // 1
    // fun函數的直接對象是O2 
    o1.o2.fun()  // 2
```

顯示綁定

經過 call() ,bind() ,apply() 方法, 把對象綁定到this上。叫作顯示綁定。

``` 
    var a = 1;
    functiont fun(){
        console.log(this.a)
    }
    var o = {
        a : 0;
    }
    fun()  // 1   獨立調用
    fun.call(obj); // 0   
```

在javascript中新增了一些內置函數,具備顯式綁定的功能,例如數組的迭代方法:map()、forEach()、filter()、some()、every()

```
     var a = 'windows';
    function fun(e){
        console.log(e,this.id)
    }
    var o = {
        a : 'o-object';
    }
    [1,2,3].forEach(fun) // 1 'windows'  2 'windows'  3 'windows'
    // 當咱們指定了綁定對象,this 就會改變
    [1,2,3].forEach(fun,obj ) // 1 'o-object'  2 'o-object'  3 'o-object'
```

隱式丟失

指的是,隱式綁定的對象有時候會出現綁定對象的丟失,從而默認綁定到windows,主要是賦值操做。
  1. 函數別名
var a = 0;
    function fun(){
        console.log(this.a)
    }
    var o = {
        a : 2;
        fun : fun;
    }
    // 在這裏出現賦值操做,使得o.fun 有了新的別名bar 形成了隱私丟失。
    // 由於只是把fun函數賦給了foo,而foo與o對象則毫無關係。 
    var foo = o.fun;
  1. 參數傳遞
    常見的一個例子:
var a = 0;
    function fun(){
        console.log(this.a);
    }
    var o = {
        a : 1;
        fun : fun;
    }
    // 其實 o.fun 在做爲參數傳遞時候, 也是一個賦值操做。
    // 一樣的道理 只是把fun函數賦給了setTimeout 的一個形參  ,而與o對象則毫無關係。
    setTimeout(o.fun,100) // 0
  1. 間接引用
function fun(){
        console.log( this.a );
    }

    var a = 0;
    var o1 = {a : 1, fun : fun};
    var p2 = {a : 2};

    o1.fun() // 1 方法調用
    //將o1.fun函數賦值給o2.fun函數,而後當即執行。至關於僅僅是fun函數的當即執行
    (o2.fun = o1.fun)();//0
    // 注意上下兩種的區別
    o2.fun = o1.fun;
    o2.fun() // 2

其實 在 javascript 內存角度上 O 和 o.fun 是存儲在不一樣的地址上的。 只有o.fun() 纔算是 從o 對象上去調用fun。不然,默認的是直接調用方法。所以綁定到了windows上。windows

(o2.fun = o1.fun)();//0
    (false || 01.fun)();//0
    (1, o1.fun)();//0
  1. 實現一個改變不了的this的綁定
    利用顯示綁定手段,能夠是this不能被修改。就是將函數的調用封裝起來 ,顯示的綁定this對象。數組

    var a = 0;
        function fun(){
            console.log(this.a)
        }
        var o = {
            a : 2;
        }
    
        var foo = function(){
            fun.call(o) // 封裝調用,顯示綁定this對象
        }
    
        foo() // 0
        setTimeout(foo,100);//2
        foo.call(window);//2
相關文章
相關標籤/搜索