this的作用

在面向对象编程中,this(或类似的关键字如self)用于引用当前对象实例。JavaScript虽然支持面向对象编程,但它的this机制更加灵活

this的指向

this在浏览器全局作用域下指向window,在node中执行一个空对象{},因为node在执行代码时会将js打包成一个模块进行加载、编译,放到一个函数中,再执行这个函数的call({})方法。 通常情况下都是出现在函数中。

this的绑定规则

默认绑定:独立函数调用,可以理解成有没有被绑定到某个对象上进行调用

var obj = {
  eating: function () {
    console.log(this);
  },
};
obj.eating();//obj显示绑定:在隐式绑定时,必须在调用函数的对象中有一个对函数的引用,比如一个属性,就是这个属性将函数的this绑定到该对象上。如果不希望有这个引用,又想对函数有一个引用,那么可以通过call、apply和bind方法。因为这些方法显示地指定了this地指向,所以被称为显示绑定。

javascript中的apply、call和bind

  • 1.创建一个全新的对象;
  • 2.这个新对象会被执行prototype连接;
  • 3.这个新对象会绑定到函数调用的this上(this的绑定在这个步骤完成);
  • 4.如果函数没有返回其他对象,表达式会返回这个新对象;
function Person(name) {
  console.log(this); // Person {}

  this.name = name;
}

var p = new Person("sun");
console.log(p); // Person {name: "sun"}优先级:
  • new绑定 > 显式绑定 > 隐式绑定 > 默认绑定
  • bind的优先级低于new
  • null或undefined作为this绑定会被忽略,转为默认绑定

一些函数的this分析

nums.forEach((item,index,arr) => {})箭头函数编写优化

1,如果有一个参数()可以省略。

nums.forEach(item=>{})2,如果函数执行体只有一行代码,那么可以省略大括号,并且这行代码的返回值会作为整个函数的返回值

nums.forEach(item => console.log(item)) nums.filter(item => true)3,如果函数执行体只有返回一个对象,那么需要给这个对象加上()

var foo = () => {
  return { name: "abc"}
}
var bar = () => ({name: "abc"})箭头函数中的this箭头函数不适应this的四种标准规则,不绑定this,而是根据外层作用域来决定this。
这里使用settimeout来模拟网络请求,然后拿到obj对象,设置data;

不用箭头函数的情况: 拿到的this是window,需要在外层定义:this = this,在setTimeOut的回调函数中使用this就代表了obj对象。

var obj = {
  data: [],
  getData: function () {
    var _this = this;
    setTimeout(function () {
      var res = ["abc", "cba", "nba"];
      _this.data.push(...res);
    }, 1000);
  },
};使用箭头函数:
箭头函数不绑定this对象,this引用就会从上层作用域中找到对应的this
var obj = {
  data: [],
  getData: function () {
    setTimeout(() => {
      var res = ["abc", "cba", "nba"];
      this.data.push(...res)
    }, 1000);
  },
};如果getData也是一个箭头函数,那么settimeout中的回调函数中this指向谁呢?
window