js之this指向问题

59 阅读2分钟

一、this的指向问题

this作为JavaScript中的一个关键字,它的复杂度很高,主要原因是它所处不同场景的代表的指向是不一样的。非严格模式下this指向默认是window,严格模式下默认是undefined

二、this指向实例场景

  • 全局环境
  • 普通函数调用
  • call/apply函数调用
  • 对象属性方法调用
  • 构造函数调用
  • 箭头函数
  • 事件绑定中的this

2-1 全局环境

在全局环境中无论是否是严格模式,this 均指向全局对象,window

// 在浏览器中, window 对象同时也是全局对象:
console.log(this === window); // true

a = 37;
console.log(window.a); // 37

this.b = "MDN";
console.log(window.b)  // "MDN"
console.log(b)         // "MDN"

2-2 普通函数调用

当普通的函数,直接调用的时候,一般来说分两种情况:

  • 严格模式绑定到 undefined
  • 非严格模式绑定到全局对象 window
function fun(){
  console.log(this);  
}
function bar(){
  "use strict"; 
  console.log(this);
}
fun() // window
bar() // undefined

2-3 callapply调用的this

call和apply函数可以改变普通函数的this指向,但是不能改变箭头函数的this指向。

 var o = {
            name: 'andy'
        }

        function fun(a, b) {
            console.log(this);
            console.log(a + b);

        };
        fun.call(o, 1, 2);
var o = {
            name: 'andy'
        };

        function fun(arr) {
            console.log(this);
            console.log(arr); // 'pink'

        };
        fun.apply(o, ['pink']);
        

2-4 对象属性方法调用

作为对象属性方法调用,都指向前面调用函数的那个对象。

var student = {
            name: "tom",

            fn: function () {
                return this;
            },
        };
        console.log(student.fn() === student);   //true

2-5 构造函数中的this

        function Person(name) {
            this.name = name
        }
        var p1 = new Person('tom')
        console.log(p1.name); //tom

在构造函数中,this经过new的调用发生了改变,在使用new调用时:
1.new会在内存中新创建一个空对象,且实例化
2.new会让this指向这个新对象
3.new给这个新对象复制属性和方法
4.return这个新对象

2-6 箭头函数中的this

箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。

var obj = {
  name: "tom",
  fun() {
    setTimeout(() => {
      console.log(this);
    }, 1000);
  },
};

obj.fun() // obj

2-7 事件绑定中的this

事件源.onclik = function(){ } //this -> 事件源

事件源.addEventListener(function(){ }) //this->事件源

        var div = document.querySelector("div");
        div.addEventListener('click',function(){
            console.log(this); // this -> div
        });

        div.onclick = function(){
            console.log(this); // this -> div
        }

三、总结

this的指向是由上下文环境动态决定的