函式上下文this

敢問發表於2020-11-29

1:直接圓括號執行 this指的是window物件    IIFE也屬於圓括號直接執行  this 只想window


例1

var obj = {
    as:100,
    fun: function(){
    alert(this.as)
}
}
var b = obj.fun
b()
//輸出undefined

例2

var a = 300;
var obj = {
    a : 100,
    b:(function(){
    alert(this.a)
    })()
}
//彈出300

例3

var xiaohong = {
    name : "小紅",
    age : 25,
    hello : (function(){
        return this.age > 18? "女士" : "女生"
    })()
}
alert ("大家好,我叫" + xiaohong.name + ",我是一個" + xiaohong.hello)


結果為女生

IIFE 裡的this指的是window 所以this.age 是undefined    undefined > 18 是false  所以返回的是 女生

例4

var obj = {
    a: 100,
    fun: function() {
        var a = 200;
        alert(this.a)
    }
}
var a = 300;
var f = obj.fun
f()
//結果300

解析:條用的時候是圓括號直接呼叫的  所以這裡this指向了window   而全域性變數都是window物件的屬性  →最後彈出300(其它的a都是障眼法)

2 從物件中呼叫或者陣列列舉執行的函式  上下文this指的是這個物件或者陣列

例1

function fun1(a, b, c) {
    arguments[0]()
}

function fun2(a, b, c, d, e) {
    alert(this.length)
}
fun1(fun2, 9, 2, 4, 2, 34, 234)、
//7

解析:this指的是誰要看誰在呼叫。函式fun1呼叫的時候 函式的執行是 arguments[0]的執行 ,因為arguments是fun1的實參列表,所以第0項就是fun2函式,所以符合規則;fun2函式中的this指的就是fun1函式的arguments類陣列物件,所以length就是7

例2

function fun1(a, b, c) {
    arguments[0](1, 2, 3, 4, 5, 6)
}

function fun2(a, b, c, d, e) {
    alert(this.length) // 7
    alert(arguments.length) // 6
    alert(arguments.callee.length) // 5
    alert(this.callee.length) // 3
}
fun1(fun2, 9, 2, 4, 2, 34, 234)

解析:

與例1類似 fun2中的this指的是fun1函式,所以此時this.length指的就是fun1的arguments類陣列物件(因為是類陣列列舉執行的符合規則);

arguments本身是fun2函式自己的實參列表,所以長度是6(呼叫的時候傳了1~6的引數);

我們知道arguments.callee是fun2函式自己,所以length就是形參列表為5;

this.callee.length指的就是fun1的形參列表為3

例3

var m = 2;
var obj = {
    fun1: function() {
        return this.fun2()
    },
    fun2: fun2,
    m: 4
}

function fun2() {
    return this.m;
}
alert(obj.fun1()) 
// 4

解析  打點執行  this指向 obj    而obj.m  就是4

例4

var num = 1; // 5 , 25 , 125
var obj = {
    num: 2, // 10 , 50
    fun: (function() {
        var num = 3;
        this.num += 4;
        return function() {
            this.num *= 5;
            num *= 6; // 18 , 108 , 648 , 
            alert(num)
        }
    })()
}
obj.fun() 			// 18
obj.fun() 			// 108
alert(num) 		// 5
alert(obj.num) 	// 50
var f1 = obj.fun
f1() 				// 648
alert(num) 		// 25
alert(obj.num) 	// 50
var f2 = obj.fun
f2() 				// 3888
alert(num) 		// 125

解析: obj.fun() →IIFE只執行一次 且this指向window  所以全域性的num = 1+4 是5   接著obj.fun() this指向obj 此時 obj的num 先變成2*5 是10  。num*=6   此時num是3 所以 *6就是18  結果為18

            obj.fun()→ IIFE不再執行  所以全域性的num 是5。接著obj.fun() this指向obj 此時 obj的num 先變成10*5 是50 。num*=6   此時num是18 所以 *6就是108 結果為108

            alert(num)→ 全域性的num 就是5

            alert(obj.num)→ obj的num 就是50

           var f1 = obj.fun

           f1()→ 圓括號直接執行 this指向window  所以 this.num *= 5指的是全域性的num*5 結果25 num*=6   此時num是108 所以 *6就是648結果為648

           alert(num)  →      全域性的num 就是25

           alert(obj.num)obj的num→ 是50

           var f2 = obj.fun

           f2()→圓括號直接執行 this指向window  所以 this.num *= 5指的是全域性的num*5 結果125 num*=6   此時num是648 所以 *6就是3888結果為3888

          alert(num)→全域性的num 就是125

例5

var length = 1;
var obj = {
    length: 10,
    b: [{
        length: 20,
        fun: function() {
            alert(this.length)
        }
    }]
}
var arr = [obj, obj.b, obj.b[0], obj.b[0].fun]
arr[0].b[0].fun() // 20
arr[1][0].fun() // 20
arr[2].fun() // 20
arr[3]() // 4

解析  前邊三個最後返回的都是 物件

{

        length: 20,

        fun: function() {

            alert(this.length)

        }

    }在執行所以this指向這個物件   結果都是20 

arr[3]()  這個是陣列通過列舉法在執行   所以this指的是 這個陣列   它的length就是4

3 定時器直接呼叫,上下文是window物件

例1

var obj = {
    a: 300,
    fun: function() {
        console.log(this.a++)
    }
}
var a = 100;
setInterval(obj.fun, 1000)
//100 100 100.。。。。。。。。。。。
var obj = {
    a: 300,
    fun: function() {
        console.log(this.a++)
    }
}
var a = 100;
setInterval(function() {
    obj.fun()
}, 1000)
// 301 302 303.............

4 DOM事件中的this,指的是觸發事件的這個DOM元素

5 call()和apply()可以設定函式的上下文

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相關文章