this指向(永遠指向最後調用它的對象)
- 一般直接調用函數時,this指向window。
- 當事件調用函數時,this指向觸發該事件的對象。
- 而當調用對象的方法時,在函數中this指向擁有該方法的對象。
但是
call( ),apply( ) 和 bind( ) 都是Function的方法,所有函數都有這三個方法。
1. 相同點
都用來改變this的指向
2.不同點
接收參數的方式不同
(1)call
形式:call (this要指向對象,傳參逐個列舉(可能多個))
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
function fn1(a,b){
console.log(a+b);
}
function fn2(a,b){
//下面的this指向調用call方法的fn1,即this指向fn1,且把age爲1傳給fn1中
fn1.call(this,10,20); // 30
}
fn2(1,2);
</script>
</body>
</html>
(2)apply
形式:apply(this要指向對象,arguments) 或 fn.apply(this要指向對象, 傳參的數組)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
function fn1(a,b){
console.log(a+b);
}
function fn2(a,b){
// arguments把a,b的1,2傳給fn1。
fn1.apply(this,arguments); // 3
fn1.apply(this,[20,30]); // 50
}
fn2(1,2);
</script>
</body>
</html>
(3)bind
形式:bind(this要指向對象) 不會立即執行,並且返回一個改變this指向的函數。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
window.color = "red";
var obj = {
color: "blue"
}
function fn1(){
console.log(this.color);
}
var a = fn1.bind(obj);
//此時this指向obj. this.color則爲obj的屬性blue
a(); //blue
</script>
</body>
</html>
所以,bind後函數不會執行,而只是返回一個改變了上下文的另一個函數,而call和apply是直接執行函數。若無參數,apply與call基本沒什麼區別
注意:在一般函數中,this在調用的時候才確定,但是在箭頭函數中,一旦箭頭函數定義,它的this就已經確定,且無法改變。箭頭函數中的this指向離自己最近的非箭頭函數作用域裏。