01 直接调用
let val = 1
function func () {
console.log(this.val) //未指向,访问全局
}
func() // -> 1
02 当方法调用
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 后面传参数 列表
f3 // -> 6
// apply
f4 = f.apply(obj,[1, 2]) //apply 后面传参数 数组
f4 // -> 6
// 若不绑定 this 指向
f.bind(null, 1, 2)() // 13
f.call(null, 1, 2) // 13
f.apply(null, [1,2]) // 13
// 若重复绑定 this 指向
f5 = f.bind({val: 5})
f5(1, 2) // -> 8
f5.apply({val: 20}, [1, 2]) // this 已经被 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() 为构造函数, 并且将作用域赋给新对象 f1并执行函数,其中函数,this 也随着指向 f1
f1.val // -> 2
one more thing
箭头函数中, this
指向周围(上一级 this 指向)
bind 函数实现
以下为 bind
实现函数,以解释 bind 多次调用时 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 调用时,形成闭包,thisArg(即对象)存入函数
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
网友评论