js中this的指向问题

121 阅读2分钟

一、this的指向问题

this 作为JavaScript中的一个关键字,它的复杂度很高,主要原因是它所处不同场景的代表的指向是不一样的。

二、this指向实例场景

  • 全局环境
  • 普通函数调用
  • call/apply函数调用
  • 对象属性方法调用
  • 构造函数调用
  • 箭头函数

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 foo(){
  console.log(this);  
}
function bar(){
  "use strict"; 
  console.log(this);
}
foo() // window
bar() // undefined

2.3 callapply调用的this

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

 var o = {
            name: 'andy'
        }

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

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

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

        };
        fn.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",
  foo() {
    setTimeout(() => {
      console.log(this);
    }, 1000);
  },
};

obj.foo() // obj

三、总结

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