作者:sunshine小小倩
連接:https://juejin.im/post/6844903496253177863
來源:掘金
this 永遠指向最後調用他的對象
我常拿來判斷的想法
看他是被當作對象內的方法調用還是全局函數
直接來看例子比較好懂
var name = 'Mike'
let foo = {
name: 'Mary',
getName() {
console.log(this.name)
}
}
foo.getName() // 很明顯是Mary,因為this指向的是最後調用他的對象
window.foo.getName() // 這也很明顯是Mary,因為會是最後調用的對象(即foo)
let bar = foo.getName // 記住這是賦與內存地址給他,執行的時候並不會變成 window.foo.getName
bar() // Mike (window.bar())
這註解超級重要
// 記住這是賦與內存地址給他,執行的時候並不會變成 window.foo.getName
題外話:
不知道大家有沒有發現我這裡第一行定義是用var來定義,因為如果用let 來定義的話,並不會變成全局變量(window.name),還有這裡如果用嚴格模式會報錯
"use strict"
var name = 'Mike'
let foo = {
... // 底下都一樣
明天會開一篇出來講這裡先pass
這裡用了一個很聰明的辦法,就是:
利用_this變量去紀錄調用過程的this對象
例子:
ar name = "windowsName";
var a = {
name: "Cherry",
func1: function () {
console.log(this.name)
},
func2: function () {
var _this = this; // 這裡在調用時會是a這個對象
console.log(this); // {name: "Cherry", func1: ƒ, func2: ƒ}
setTimeout(function () {
_this.func1()
}, 100);
}
};
a.func2() // Cherry
先來看例子晚點講原理
可以發現其實三個的用法幾乎一樣,只有bind要再執行一次
var a = {
name: "Cherry",
func1: function () {
console.log(this.name)
},
func2: function () {
// apply
setTimeout(function () {
this.func1() // Cherry
}.apply(a), 100);
// call
setTimeout(function () {
this.func1() // Cherry
}.call(a), 100);
// bind
setTimeout(function () {
this.func1() // Cherry
}.bind(a)(), 100);
}
};
a.func2()
這三個都會讓函數執行喔
基本上是沒差,只是傳遞參數apply是用array而call是分批傳入
定義:
fun.apply (thisArg,[argsArray])
fun.call (thisArg[, arg1[, arg2[, ...]]])
看起來有夠複雜,其實就是最上面講得那句。直接看例子就懂了
例子:
var a ={
name : "Cherry",
fn : function (a,b) {
console.log(a + b)
}
}
var b = a.fn;
b.apply(a,[1,2]) // 3
b.call(a,1,2) // 3
bind跟他們兩個的最大區別就是
bind是創建函數,還需要手動調用
var a ={
name : "Cherry",
fn : function (a,b) {
console.log( a + b)
}
}
var b = a.fn;
b.bind(a,1,2)() // 3