11、函數內部的this指向以及如何改變函數內部的this指向


一、函數內部的this指向

調用方式 this指向
普通函數調用 window
構造函數調用 實例對象
對象的方法調用 該方法所屬對象
事件綁定方法 綁定事件對象
定時器函數 window
立即執行函數 window

1、普通函數調用

普通函數的this指向window
1 function fun() {
2     console.log('普通函數的this' + this);
3 }
4 fun();

2、構造函數調用

構造函數this指向ldh這個實例對象,原型對象里面的this指向的也是ldh這個對象

1 function Star() {};
2 Star.prototype.sing = function() {};
3 var ldh = new Star();

3、對象的方法調用

對象的方法的this指向的是對象o

復制代碼
1 var o = {
2     sayHi: function() {
3         console.log('對象方法的this' + this);
4     }
5 }
6 o.sayHi();
復制代碼

4、事件綁定方法

綁定事件函數this指向的是函數的調用者btn這個按鈕對象

1 var btn = document.querySelector('button');
2 btn.onclick = function() {
3     console.log('綁定事件函數的this' + this);
4 
5 }

5、定時器函數

定時器函數this指向的是window

1 setTimeout(function() {
2     console.log('定時器函數的this' + this);
3 }, 1000);

6、立即執行函數

立即執行函數this指向的是window

1 (function(){
2     console.log('立即執行函數的this'+this);
3 })();

 

 

 

二、改變函數內部的this指向的三種方法

1、call方法

call()方法可以調用函數,還可以改變函數內的this指向,它的主要作用是可以實現繼承

fun.call(thisArg,arg1,arg2,....)

這里將fun函數的this指向o

復制代碼
1 var o = {
2     name: 'Andy'
3 }
4 
5 function fun(a, b) {
6     console.log(this);
7     console.log(a + b);
8 }
9 fun.call(o, 1, 2);
復制代碼

將父構造函數里的this指向子構造函數的實例對象(構造函數的this指向它的實例對象)

復制代碼
 1 function Father(uname, age, sex) {
 2     this.uname = uname;
 3     this.age = age;
 4     this.sex = sex;
 5 }
 6 
 7 function Son(uname, age, sex) {
 8     Father.call(this, uname, age, sex);
 9 }
10 var son = new Son('ldh', 18, 'male');
11 console.log(son);
復制代碼

 

2、apply方法

fun.apply(thisArg,[argsArray])(傳遞的值必須包含在數組里)

apply()方法可以調用函數,還可以改變函數內的this指向,但它的參數必須是數組(偽數組)

1 var arr = [1, 33, 22, 44, 12];
2 var max = Math.max.apply(Math, arr);
3 var min = Math.min.apply(Math, arr);
4 console.log(max, min);

3、bind方法(用的最多)

bind()方法不會調用函數,但是可以改變函數內部this指向

 fun.bind(thisArg,arg1,arg2,....)

復制代碼
 1 var o = {
 2     name: 'Andy'
 3 }
 4 
 5 function fun(a, b) {
 6     console.log(this);
 7     console.log(a + b);
 8 }
 9 var f = fun.bind(o, 1, 2);
10 f();
復制代碼
下面的小案例是點擊按鈕后按鈕禁用,直到三秒后開啟按鈕
雖然定時器函數里的this指向window,但是bind(this)里面的this是在定時器函數的外面綁定的,這個this又在btns[i].onclick這個函數里面,所以這個this指向的就是btns對象
為什么這里的this.disabled的this不用btns[i]呢,因為定時器是在3秒后執行,而for循環立馬執行,這里有三個按鈕,則i為3
復制代碼
1 var btns = document.querySelectorAll('button');
2 for (var i = 0; i < btns.length; i++) {
3     btns[i].onclick = function() {
4         this.disabled = true;
5         setTimeout(function() {
6             this.disabled = false;
7         }.bind(this), 3000);
8     }
9 }
復制代碼

3、call、apply、bind總結

相同點:都可以改變函數內部的this指向

區別:

1.call和apply會調用函數,並且改變函數內部的this指向

2.call和apply傳遞的參數不一樣,apply必須以數組形式

3.bind不會調用函數,但是會改變函數內部的this指向

主要應用場景:

1.call主要用作繼承

2.apply經常跟數組有關,比如借助數學對象實現數組中的最大最小值

3.bind可用於改變定時器內部的this指向


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM