01 直接調(diào)用
let val = 1
function func () {
console.log(this.val) //未指向鹰祸,訪問全局
}
func() // -> 1
02 當(dāng)方法調(diào)用
let a = {name: 'foo', foo: function(){
console.log (this.name)
}}
let b = {name: 'bar'}
a.foo() // foo
b.bar = a.foo
b.bar() // bar
b.bar = a.foo() // foo
b.bar() // 報錯漩符,b.bar is not a funciton
03 call & apply & bind 明確顯示
let val = 10 // 全局變量 val
let obj = {val: 3}
function f(a,b) {
return a+b +this.val
}
// bind
f2 = f.bind(obj) // f.bind({val: 3}, 1)
f2(1, 2) // -> 3 // f2(2) // -> 6
// call
f3 = f.call(obj, 1, 2) //call 后面?zhèn)鲄?shù) 列表
f3 // -> 6
// apply
f4 = f.apply(obj,[1, 2]) //apply 后面?zhèn)鲄?shù) 數(shù)組
f4 // -> 6
// 若不綁定 this 指向
f.bind(null, 1, 2)() // 13
f.call(null, 1, 2) // 13
f.apply(null, [1,2]) // 13
// 若重復(fù)綁定 this 指向
f5 = f.bind({val: 5})
f5(1, 2) // -> 8
f5.apply({val: 20}, [1, 2]) // this 已經(jīng)被 bind 綁定第一個對象, 此處綁定無效
f5 // -> 8
f6.call({val: 30}, [1, 2]) // 同理
f6 // -> 8
04 new func()
let val = 1
function func (val) {
this.val = val
}
let f1 = new func(2)
//new func() 為構(gòu)造函數(shù), 并且將作用域賦給新對象 f1并執(zhí)行函數(shù)南片,其中函數(shù)沐旨,this 也隨著指向 f1
f1.val // -> 2
one more thing
箭頭函數(shù)中采郎, this
指向周圍(上一級 this 指向)
bind 函數(shù)實現(xiàn)
以下為 bind
實現(xiàn)函數(shù)寺谤,以解釋 bind 多次調(diào)用時 this 指向問題
function bind2(f, thisArg, ...fixedArgs) {
return function (...restArgs) {
return f.apply(thisArg, [...fixedArgs, ...restArgs])
}
}
function f(a) {
return a + this.val
}
f2 = bind2(f, {val: 1}) // bind2 調(diào)用時隙畜,形成閉包榛搔,thisArg(即對象)存入函數(shù)
f2(2) // -> 3
f3 = f2.call({val: 2, 3}) // call使用時诺凡,thisArg 已被bind2時閉包指向{val: 1}
f3 // -> 3
參考:
https://zhuanlan.zhihu.com/p/23804247
https://segmentfault.com/a/1190000015438195