我們都知道,在javaScript中定義的函數最外層中如果有this對象,則this就指向函數調用者,例如:
const student = { name: '趙六', address: '杭州', greeting: function() { console.log(`我叫 ${this.name},來自 ${this.address}`); }, }; student.greeting();
我叫 趙六,來自 杭州
這裏的greeting方法中有this對象,調用者爲student對象,則打印的內容就是student中的數據。
問題:當在定義一個student1對象時,實現和student.greeting()同樣功能,打印數據,是否還需要重新定義一個方法,如:
const student1 = { name: '張三', address: '北京', greeting: function() { console.log(`我叫 ${this.name},來自 ${this.address}`); }, };
其實沒有必要,這裏就可以使用 call() apply() 或 bind()方法,通過改變this的指向來複用student的greeting方法,使用如下:
const student1 = { name: '張三', address: '北京', }; student.greeting.call(student1); student.greeting.apply(student1); student.greeting.bind(student1)();
我叫 張三,來自 北京
我叫 張三,來自 北京
我叫 張三,來自 北京
這裏就可以看到,call() apply() 和 bind()方法的共同點就是改變this的指向,只不過bind()方法的使用和call、apply不太一樣
上面講述了call() apply() 和 bind()的共同點,下面看下這個三個方法的不同點,重點在參數傳遞上,如下:
修改student方法:
const student = { name: '趙六', address: '杭州', greeting: function(age, grade) { console.log(`我叫 ${this.name},來自 ${this.address}, 今年 ${age} 歲, 讀${grade}年級`); }, };
調用方法:
student.greeting.call(student1, 12, 5); student.greeting.apply(student1, [9, 3]); student.greeting.bind(student1, 10, 4)(); student.greeting.bind(student1, [10, 4])();
我叫 張三,來自 北京, 今年 12 歲, 讀5年級
我叫 張三,來自 北京, 今年 9 歲, 讀3年級
我叫 張三,來自 北京, 今年 10 歲, 讀4年級
我叫 張三,來自 北京, 今年 10,4 歲, 讀undefined年級
從上面結果可以看到
call 、bind 、 apply 這三個函數的第一個參數都是 this 的指向對象,第二個參數不盡相同:
call的參數是從第二個參數依次傳入;
apply的所有參數都必須放在一個數組中傳入;
bind除了返回是函數以外,它 的參數和call 一摸一樣。