千鋒教育JavaScript全套視頻教程(10天學(xué)會Js,前端javascrip

改變this指向
一.call,apply,bind的區(qū)別 -
它們的作用是相同的,都是動態(tài)的修改當(dāng)前函數(shù)內(nèi)部的this的指向。
1.執(zhí)行方式不同:
call和apply是改變后就立即執(zhí)行函數(shù),bind改變后不會立即執(zhí)行;而是返回一個新的函數(shù),需要再次調(diào)用。
function fn() {
console.log(this);
}
fn();//this->window
fn.call(1);//this->1 立即執(zhí)行
fn.apply(1);//this->1 立即執(zhí)行
fn.bind(1)()//this->1 再次調(diào)用
2.傳參方式不同:
call 第一個參數(shù)this指向,從第二個參數(shù)開始就是函數(shù)的參數(shù)。
bind 第一個參數(shù)this指向,從第二個參數(shù)開始就是函數(shù)的參數(shù),返回的是函數(shù)體,繼續(xù)通過調(diào)用再次傳入?yún)?shù)。
apply第一個參數(shù)this指向,第二個參數(shù)是數(shù)組,函數(shù)自身的參數(shù)放到數(shù)組里面。
var num = 1;//var聲明的變量也是window的屬性
function sum(a, b) {
console.log(this.num + a + b);
}
sum.call(window, 2, 3);//this.num = 1 結(jié)果6
sum.bind(window, 2, 3)();//this.num = 1 結(jié)果6
sum.bind(window)(2, 3,);//this.num = 1 結(jié)果6 繼續(xù)通過調(diào)用再次傳入?yún)?shù)
sum.apply(window, [2, 3]);//this.num = 1 結(jié)果6 這里不一樣
3.修改this的性質(zhì)不同
call、apply只是臨時的修改一次,修改就是call和apply方法使用的那一次;當(dāng)再次調(diào)用原函數(shù)的時候,它的指向還是原來的指向。
var obj = {
a: 100
}
var a = 1;//var聲明的變量也是window的屬性
function fn() {
console.log(this.a);
}
fn();//this->window 1
fn.call(obj);//100
fn.apply(obj);//100
// 當(dāng)再次調(diào)用原函數(shù)的時候,它的指向還是原來的指向。
fn()//this->window 1
bind是永久修改函數(shù)this指向,但是它修改的不是原來的函數(shù);而是返回一個修改過后新的函數(shù),此函數(shù)的this永遠(yuǎn)被改變了,綁定了就修改不了。
var obj = {
a: 100
}
var a = 1;//var聲明的變量也是window的屬性
function fn() {
console.log(this.a);
}
var newFn = fn.bind(obj);//這里返回新函數(shù),修改的就是返回的新函數(shù)的this
newFn(); //this->obj 100
newFn(); //this->obj 100
newFn(); //this->obj 100
newFn(); //this->obj 100
newFn.call(window);//修改返回的新函數(shù),將其this指向window,但是無法修改,this繼續(xù)指向obj 100
newFn.call(1);//修改返回的新函數(shù),將其this指向1,但是無法修改,this繼續(xù)指向obj 100
newFn.call(2);//修改返回的新函數(shù),將其this指向2,但是無法修改,this繼續(xù)指向obj 100
newFn.call(3);//修改返回的新函數(shù),將其this指向3,但是無法修改,this繼續(xù)指向obj 100