共计 1232 个字符,预计需要花费 4 分钟才能阅读完成。
每个函数的 this 是在调用的时候被绑定的,完全取决于函数的调用位置。表现特征有点像动态作用域,从就近查找调用栈,来判断 this 指向谁。
1. 默认绑定(全局环境)
var a = 2;
function foo(){
console.log(this.a);
}
foo() //2
这个例子中,foo()在全局环境中被裸着调用,毫无上下文。所以这时 this 被调用的时候从内向外寻找 a,可以找到全局变量 a。
但是在严格模式 (strict mode) 中,默认绑定就不生效。
var a = 2;
function foo(){
“use strict”// 严格模式
console.log(this.a);
}
foo() //undefined
2. 隐式绑定(对象环境)
var obj = {
a: 2,
foo:foo
}
function foo(){
console.log(this.a);
}
obj.foo()//2
foo()//undefined
这种绑定并不靠谱,比如在回调的情况下。
function foo(){
console.log(this.a);
}
var obj = {
a:2,
foo:foo
}
setTimeout(obj.foo, 100);//undefined
为什么不靠谱, 在 setTimeout 时调用,this 指向了 setTimeout 这个函数而不再是 obj 这个对象。
3. 显式绑定(call, apply, bind)
隐式绑定把函数直接绑定到了目标对象的一个属性上。如果我们不想在对象内部包含函数引用,而想直接在某个对象上运用函数。就要用显式绑定。
function sayName(){
console.log(this.name);
}
sayName(); // 直接调用这个函数将找不到 this, 返回 undefine。
person1 = new Person(“leo”);
//sayName 使用 call()将 this 指向 person1 就好了。
sayName.call(person1);//”leo”
function sayNameAndMore(age, gender){
console.log(this.name + age + gender)
}
//apply 用法
sayNameAndMore.apply(person1, [” 18 “,” male “]);//leo 18 male
共同点
都是被函数调用,如 someFunction.call(obj), someFunction.apply(obj)
都将 this 指向填入的参数 obj,someFunction 函数定义中的所有 this 就可以按照想要的效果进行。
区别
call 和 apply 直接执行,bind 之后执行。
call 只接受一个参数,而 apply 接受一个参数数组。
React 中的 bind
React 中我们总是要把事件 handle 函数 bind 到组件上。是因为事件触发是异步的,如果不 bind,触发时的 this 就是当时的 dom 元素。就像上面隐式绑定不靠谱的情况一样。
new 绑定
new 绑定涉及更多知识点,不在这里写