一直以来,我对js中的this指向问题都不是特别清楚。平时在写代码时只知道,对象中的方法如果使用this,则这个this代表的就是这个对象,但是对其使用和判断并不能信手拈来,好多时候还是得过且过,不明所以。所以我查看了很多资料,彻底扫除this关键字的盲区,也希望对大家有所帮助。
js中的this其实是函数调用的上下文,在我看来这个定义包括两方面:1、在一个函数中,this是调用这个函数的对象;2、一个函数可能会被以不同的方式调用,不同的调用方式下,this的含义不同。因此,函数中this的含义可以视为是在运行时确定的。
总结了以下几种情况的this指向:
1、全局直接调用函数时,在非严格模式中,函数中的this代表着全局对象window或者global,在严格模式中,函数中的this为undefined。
function angry_it_man(){
"use strict"
if(this == undefined){
console.log('欢迎关注微信公众号:愤怒的it男');
}else{
console.log(this);
}
};
angry_it_man();
function angry_it_man(){
if(this == undefined){
console.log('欢迎关注微信公众号:愤怒的it男');
}else{
console.log(this);
}
};
angry_it_man();
2、通过对象调用方法时,对象方法中的this代表着该对象。
var name = '欢迎关注微信公众号:愤怒的it男';
var angry_it_man = {
name : '欢迎关注微信公众号:angry_it_man',
say : function(){
return this.name;
},
}
console.log(angry_it_man.say()); // 对象中的this指向angry_it_man对象
f = angry_it_man.say; // 将对象中的say抽离
console.log(f()); // 对象中的this指向全局对象window或者global
3、使用构造函数创建对象时,构造函数中的this代表着new出来的对象。
var name = '欢迎关注微信公众号:愤怒的it男';
var Angry_IT_Man = function(){
this.name = '欢迎关注微信公众号:angry_it_man';
this.say = function(){
return this.name;
}
}
var angry_it_man = new Angry_IT_Man();
console.log(angry_it_man.say()); // 对象中的this指向angry_it_man对象
f = angry_it_man.say; // 将对象中的say抽离
console.log(f()); // 对象中的this指向全局对象window或者global
4、使用call、apply、bind绑定的,this指向绑定的对象。
call的调用方式为:function.call(argthis,arg1,arg2,…),apply的调用方式为:function.apply(argthis,[arg1,arg2,…]),call和apply的第一个参数就是function的调用上下文,也就是函数中的this值。
var angry_it_man1 = {
name: '欢迎关注微信公众号:愤怒的it男',
}
var angry_it_man2 = {
name: '欢迎关注微信公众号:angry_it_man',
}
var say = function (){
return this.name;
}
console.log(say.call(angry_it_man1));
console.log(say.apply(angry_it_man2));
bind的调用方式为:function.bind(argthis,arg1,arg2,…),bind方法不会立即执行函数,而是返回一个新函数,这个新函数的this值被绑定到argthis对象上,一旦绑定成功,则this不会再变,重新绑定也无效。
var angry_it_man1 = {
name: '欢迎关注微信公众号:愤怒的it男',
}
var angry_it_man2 = {
name: '欢迎关注微信公众号:angry_it_man',
}
var it_man = {
say:function (){
return this.name;
}
}
var func = it_man.say.bind(angry_it_man1);
console.log(func());
console.log(func.apply(angry_it_man2)); // 经过bind绑定后this不再改变
console.log(func.bind(angry_it_man2)()); // 重新绑定无效
1、箭头函数中的this等于其定义环境的this,并且箭头函数一经构建,其this指针就被绑定,且不能被任何方法改变。
如果箭头函数在某个函数中被定义,其this值等于外部函数被执行时的this值。
var name = '欢迎关注微信公众号:愤怒的it男';
var Angry_IT_Man = function(){
this.name = '欢迎关注微信公众号:angry_it_man';
this.say = ()=>{return this.name;};
}
var angry_it_man = new Angry_IT_Man()
console.log(angry_it_man.say()) // 对象中的this指向angry_it_man对象
f = angry_it_man.say; // 将对象中的say抽离
console.log(f()) // 箭头函数的this固定指向angry_it_man
如果箭头函数的定义不在任何函数中,则其this为全局对象。
var name = '欢迎关注微信公众号:愤怒的it男';
var angry_it_man = ()=>{
this.name = '欢迎关注微信公众号:angry_it_man';
}
angry_it_man(); // 箭头函数是在最外围创造的,因此其this指向window
console.log(name)
1、在HTML事件句柄中,this指向接收事件的HTML元素。
2、立即执行函数(IIFE),this会100% 指向全局对象window或者global。
var name = '欢迎关注微信公众号:愤怒的it男';
(function(){
console.log(this.name);
})();
3、setTimeout 中传入的函数,this会100% 指向全局对象window或者global。
var name = '欢迎关注微信公众号:愤怒的it男';
var angry_it_man = {
name: '欢迎关注微信公众号:angry_it_man',
say: function() {
setTimeout(function(){
console.log(this.name);
},3000)
}
}
angry_it_man.say();
4、setInterval 中传入的函数,this会100% 指向全局对象window或者global。
var name = '欢迎关注微信公众号:愤怒的it男';
var angry_it_man = {
name: '欢迎关注微信公众号:angry_it_man',
say: function() {
setInterval(function(){
console.log(this.name);
},3000)
}
}
angry_it_man.say();
欢迎关注作者微信公众号【愤怒的it男】