淺談 js 中的 this 指向問題

追_光_者發表於2019-03-07
this 在前端是一個難點,也是一個痛點。首先this在宣告的時候是不確定的,只有在被呼叫了之後才知道this的指向。主要有一下集中呼叫方式:
複製程式碼

1: 函式名()直接呼叫 此時的this指向window

```
    function fn() {
    	var name = '我是fn裡面的name'
    	console.log(this.name)
    }
    
    var name = '我是window裡面的name'
    
    fn()
    window.fn()
    
    //  結果
    我是window裡面的name
    我是window裡面的name
```
複製程式碼

2: window下預設的函式如:setTimeout this也指向window

```
    setTimeout(function() {
        var name = '我是setTimeout裡面的name'
        console.log(this.name)
    }, 1000)
    
    var name = '我是window裡面的name'
    
    //  結果
    我是window裡面的name
```
複製程式碼

3: Object.函式名()的呼叫 此時的this指向該Object

```
    var name = '我是window裡面的name'
    var obj = {
        name: '我是obj裡面的name',
        getName: function() {
            console.log(this.name)
        }
    }
    
    obj.getName()
    
    var temp = obj.getName
    temp()
    
    //  結果
    我是obj裡面的name
    我是window裡面的name    (宣告一個全域性變數temp然後將函式賦值給它,最後通過window呼叫)var name = '我是window裡面的name'
    var obj = {
        name: '我是obj裡面的name',
        getName: function() {
            console.log(this.name)
        }
    }
    
    obj.getName()
    
    var temp = obj.getName
    temp()
    
    //  結果
    我是obj裡面的name
    我是window裡面的name    (宣告一個全域性變數temp然後將函式賦值給它,最後通過window呼叫)s
```
複製程式碼

4: new運算子中的this指向該例項

```
    var name = '我是window裡面的name'
    function Fn() {
        this.name = '我是Fn函式裡面的name'
        this.getName = function() {
            console.log(this.name)
        }
    }
     
    var fn1 = new Fn()
    var temp = fn1.getName
    
    fn1.getName()
    temp()
    
    //  結果
    我是Fn函式裡面的name
    我是window裡面的name    (宣告一個全域性變數temp然後將函式賦值給它,最後通過window呼叫)
```
複製程式碼

5: 陣列元素為函式時,通過陣列來呼叫函式,此時的this為該陣列

```
    function yideng(a, b, c) {
        console.log(this.length)
        console.log(this.callee.length)
    }

    function fn(d) {
    	arguments[0](10, 20, 30, 40, 50)
    }

    fn(yideng, 10, 20, 30)
    
    // 結果
    4
    1   (callee是arguments物件的一個屬性,指向當前執行的那個函式)
```
複製程式碼

6: bind,call,apply 對 this 的重新繫結,this都指向第一個引數

```
    function fn() {
    	var name = '我是fn裡面的name'
    	console.log(this.name)
    }
    
    var name = '我是window裡面的name'
    
    fn()
    fn.bind({name: '我是bind裡面的name哦'})()   // 注意bind之後返回的是一個函式哦
    fn.call({name: '我是call裡面的name哦'})
    fn.apply({name: '我是apply裡面的name哦'})
    
    // 結果
    我是window裡面的name
    我是bind裡面的name哦
    我是call裡面的name哦
    我是apply裡面的name哦
```
複製程式碼

7: 箭頭函式中this指向最近一層中的this,不決定於誰呼叫

```
    function fn() {
    	var name = '我是fn裡面的name'
    	console.log(this.name)
		function fn2() {
			console.log(this.name)
		}
		
		fn2()
    }
    
    fn.call({name: '我是call裡面的name哦'})
    
    //  結果
    我是call裡面的name哦
    我是window裡面的name
    
    function fn() {
    	var name = '我是fn裡面的name'
    	console.log(this.name)
		var fn2 = () => {
			console.log(this.name)
		}
		
		fn2()
    }
    
    fn.call({name: '我是call裡面的name哦'})
    
    //  結果
    我是call裡面的name哦
    我是call裡面的name哦
```複製程式碼

相關文章