Js中this指向的几种情况总结

178 阅读2分钟

js中this指向可谓是js的一个坑,今天写一篇日记总结下this的几种情况,首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数运行时才能确定this到底指向谁。

实际场景

情形一:DOM事件绑定中

给元素的某个事件行为绑定方法,事件触发,方法执行,此时方法中的this一般指的是当前元素本身,注意:如果在事件处理函数中执行另外一个函数,那么该函数中的this指向的是window。

<button id="btn">点击我</button>
<script>
    // DOM0级事件绑定
     btn.onClick = function(){
     console.log(this);  // 此时 this指向的是当前元素
    }
    // DOM2级事件绑定
  	btn.addEventListener('click',function(){
      conosle.log(this); // => 元素本身
    },false)
    // DOM2级兼容IE6,7,8写法
  	btn.attachEvent('click',function(){
      conosle.log(this) // => 元素本身
    })
    // 特殊情况
    var fun = function(){
      console.log(this)
    }
    btn.onclick = function(){
      fun(); // 此时fun中的this指向window
    }
</script>

情形二:普通函数执行

普通函数执行,它里面的this指向的是谁,取决于方法执行前面是否有"点",有的话,“点”前面是谁this就是谁,没有this就指向window(严格模式下是undefined)

function fun1(){
 console.log(this);
}
let obj = {
  name:'秃头鱼',
  fn:fun1
}
fun1();
obj.fn();
obj.hasOwnProperty('name') // => hasOwnProperty:用来检测某个属性名是否属于当前对象的私有属性,in是用来检测是否为其属性(不论私有还是共有)
console.log(obj.hasOwnProperty('name')) // => this:obj TRUE
console.log(obj.__proto__.hasOwnProperty('name')); // => this:obj.__proto__(Object.prototype)  FALSE
console.log(Object.prototype.hasOwnProperty.call(obj,'name')) <=> obj.hasOwnProperty('name')

情形三:自执行函数执行

自动执行函数执行中的this一般情况下指向window。

var fun1 = (function(){
  console.log(this); // => this:window
})();

情形四:构造函数执行

在构造函数执行(new xxx),函数中的this指向的是当前的实例。

function Person(){
  console.log(this);
  // this.xxx = xxx 是给当前实例设置私有属性
}
let p1 = new Person();

情形五:箭头函数中的this

箭头函数中的没有自身的this,用的的this都是其上下文中的this。

let obj = {
  fn:()=>{
    console.log(this); // => this:window
  },
  fun2:function(){
    console.log(this) // => obj
    return function(){
      console.log(this); // => window
    }
  }
}
obj.fn();

注意:箭头函数中没有的东西很多,例如:

  • 它没有原型Prototype(也就是没有构造器)不能被new执行
  • 它没有arguments实参集合(可以基于...args剩余运算符获取)

情形六:定时器中的this

定时器中的this一般情况指向window

let obj = {
  name:'秃头鱼',
  fn:function(){
    setTimeout(function(){
      cosnole.log(this); // this指向的是window,解决方法,改为箭头函数或者bind,或者_this = this;
      this.name = '程序员';
    },1000)
  }
}

总结

  • 自执行函数、定时器中的this一般指向window
  • 箭头函数中没有this,用的this都是其上线中的this
  • 构造函数中的this一般指向的是当前实例
  • 其余普通函数中的this取决于方法前面是否有"点",如果有,“点”前面是谁,this就是谁,否则this指向window。