JS中this的9种指向详解(web前端开发javascript语法基础)

一直以来,我对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男】

你可能感兴趣的:(JavaScript,前端,javascript,开发语言)