我们首先来看一下什么是this?
在传统的面向对象的语言中,如Java , this关键字用来表示当前对象本身,或者当前对象的一个实例,通过this关键字可以获取到当前对象的属性和调用方法,在js中this表现得略有不同, 在规范中写到:this关键字执行为当前执行环境得thisBinding. MDN中写到:绝大多数情况中,函数得调用方式决定了this得值。 可以理解为,在js中this得指向是调用时决定得,而不是创建时决定得,这会倒置this得指向发生变化,简洁来讲,this具有运行期绑定得特性。 参考如下:developer.mozilla.org/zh-CN/docs/…
1、调用得位置 需要先了解调用位置,调用位置就是函数在代码中被调用得位置,而不是声明得位置, 通过分析调用栈到达当前执行位置所调用得所有函数,可以找到调用位置。
function kkb(){
console.log('kkb');
kkb2();
}
function kkb2(){
console.log('kkb2');
kkb3();
}
function kkb3(){
console.log('kkb3');
}
kkb();
当我们调用kkb()时,它会从此调用kkb()\kkb2()\kkb3(); 对于kkb3();调用位置是在kkb2()中, 对于kkb2();调用位置是在kkb()中, 对于kkb();调用位置时全局作用域中; 可以看出,调用位置应该是当前正在执行得函数得前一个调用中。
全局山下文
在全局执行上下文中this都指代全局对象。
1、this等价于window对象 2、var === this. ===window
console.log(window === this); // true
var A = 2;
this.B = 4;
window.C = 6;
console.log(A + B + C); // 12
函数上下文 在函数内部,this得值取决于函数被调用得方式;
1、直接调用
this指向全局变量
function kkb(){
return this;
}
console.log(kkb() === window);
//true
call()、 apply()
this指向绑定的对象上;
var persons = {
name:"kkb",
age:8
}
function per(sex){
console.log(this.name,this.age,sex)
}
per.call(persons,"girl");
per.apply(persons,["girl"])
可以看到,定义了一个per函数是用来输出name\age\sex,其中本身没有name,age属性,我们将这个函数绑定到person对象上,输出了本属于person的属性,说明此时this是指向对象person的。 如果传入一个原始值(字符串,布尔值,或者数字类型)来当做this的绑定对象,这个原始值会被 转换为他的对象形式。 call和apply从this的绑定角度上来说是一样的,唯一不同的是他们的第二个参数
bind()
this将永久地被绑定到了bind的第一个参数
bind和call、apply有些相似,但是实际上bind方法返回的是一个修改过后的函数;
同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。
var a = {
user:"安琪拉",
fn:function(e,d,f){
console.log(this.user); //安琪拉
console.log(e,d,f); //1,2,3
}
}
var b = a.fn;
var c = b.bind(a,1);
c(2,3);
2、箭头函数
所有的箭头函数都没有自己的this,都指向外层。 具体的官网例子: developer.mozilla.org/zh-CN/docs/…
3、作为对象的一个方法
this指向调用函数的对象。
var person = {
name: "kkb",
getName: function(){
return this.name;
}
}
console.log(person.getName()); // kkb
4、作为一个构造函数
this被绑定到正在构造的新对象。
通过构造函数创建一个对象其实执行这样几个步骤:
- 创建新对象
- 将this指向这个对象
- 给对象赋值(属性、方法)
- 返回this
所以this就是指向创建的这个对象上。
作为一个DOM事件处理函数
this指向触发事件的元素,也就是始事件处理程序所绑定到的DOM节点。
var ele = document.getElementById("id");
ele.addEventListener("click",function(e){
console.log(this);
console.log(this === e.target); // true
})
HTML标签内联事件处理函数
this指向所在的DOM元素
Click Me
jQuery的this 在许多情况下JQuery的this都指向DOM元素节点。
$(".btn").on("click",function(){
console.log(this);
});
综合来讲:
如果要判断一个函数的this绑定,就需要找到这个函数的直接调用位置。然后可以顺序按照下面四条规则来判断this的绑定对象:
由new调用:绑定到新创建的对象
由call或apply、bind调用:绑定到指定的对象
由上下文对象调用:绑定到上下文对象
默认:全局对象
注意:箭头函数不使用上面的绑定规则,根据外层作用域来决定this,继承外层函数调用的this绑定。