总结JavaScript中this指向的问题

一、什么是this、this又指向谁?
1.1 什么是this

定义:this是包含它的函数作为方法被调用时所属的对象。这句话听起来有点绕嘴,但一个多余的字也没有,定义非常准确,我们可以分3部分来理解它!
1、包含它的函数。
2、作为方法被调用时。
3、所属的对象

1.2 this指向谁

谁最终调用函数,this就指向谁。

二、this指向特点

1、this指向的只可能是对象。
2、this指向谁,不取决于this写在哪儿,而取决于函数在哪儿调用。
3、this指向的对象,称之为函数的上下文(函数的调用者)。

1、直接调用

直接调用函数,this指向window。

	function fn() {
      var a = 1;
      console.log(this); // window
      console.log(this.a); // 2
    }
    var a = 2;
    fn();
2. 对象的形式调用

在对象上调用函数,this指向调用的那个对象。

	function xx() {
      var a = 1;
      console.log( this); // obj ====> ({a: 3, xx: ƒ})
      console.log(this.a); // 3
    }
    var a = 2;
    var obj = {
      a: 3,
      xx: xx,
    };
    obj.xx();
3. 构造函数(new操作符)

在构造函数中 this 永远绑定在fn上,也就是说他指向new出来的那个对象,this不会发生改变。

	function Fn() {
      var a = 1;
      console.log(this); // Fn {}
      console.log(this.a); // undefined
    }
    var a = 2;
    var fn = new Fn();
4. 定时器(匿名函数)调用

定时器函数作为window内置函数的回调函数调用,其调用的是window.setTimeout,此时的this指向window

	var a = 1;
    setTimeout(function () {
      var a = 2;
      console.log(this); // window
      console.log(this.a); // 1
    }, 1000);
5. 在箭头函数中调用

学过ES6都知道箭头函数本身其实是没有thisarguments的,实际上箭头函数中的this取决于包裹着箭头函数的第一层普通函数的this,大白话就是离他最近的父级函数,来看一个例子:

	function ft() {
      var a = 1;
      return () => {
        console.log(this); // window
        console.log(this.a); // 2
      };
    }
    var a = 2;
    ft()();

由上面的例子不难看出,包裹着箭头函数的第一个普通函数是ft函数,由于ft函数指向window,即在箭头函数中调用this指向window

6. call、apply、bind

callapplybind这些改变上下文的函数其this指向取决于第一个参数。如果第一个参数为''nullundefined等,则this指向window;如果传递的有参数则this指向第一个参数。
首先看不传参数时的情况:

	function ff() {
      var a = 1;
      console.log(this);
      console.log(this.a);
    }
    var obj = {
      a: 3,
    };
    var a = 2;
    ff.call(); // window  2
    ff.apply(); // window  2
    var ff1 = ff.bind() // window  2
    ff1()

然后给他们传递参数时的情况:

function ff() {
      var a = 1;
      console.log(this);
      console.log(this.a);
    }
    var obj = {
      a: 3,
    };
    var a = 2;
    ff.call(obj); // obj ====> { a: 3 } // 3
    ff.apply(obj); // obj ====> { a: 3 } // 3
    var ff2 = ff.bind(obj); // obj ====> { a: 3 } // 3
    ff2();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章