总的来说:

普通函数中this总是代表着它的直接调用者

箭头函数中this默认指向该函数所在的作用域指向的对象

在线调试
具体情况来看:
(1) 由new创建的被调用函数
这种情况下js会创建出一个新对象,被调用函数中的this指向的就是这个新创建的函数。

  1. function ConstructorExample() {
  2. console.log(this);
  3. this.value = 10;
  4. console.log(this);
  5. }
  6. new ConstructorExample();

(2) 通过apply、call或者bind的方式触发的函数
这种情况下,函数中的this指向传入函数的第一个参数。

  1. function fn()
  2. {
  3. console.log(this);
  4. }
  5. var obj = { value: 5 };
  6. var boundFn = fn.bind(obj);
  7. boundFn();
  8. fn.call(obj);
  9. fn.apply(obj);

(3) 一个函数是某个对象的方法,并且对象使用句点符号触发函数
这种情况下,this指向的就是该函数作为那个对象的属性的对象,也就是,this指向句点左边的对象。

  1. var obj = {
  2. value: 5,
  3. printThis: function() {
  4. console.log(this);
  5. }
  6. };
  7. obj.printThis();

(4)引用式的调用
它将自动隐式编程全局对象的属性——window,即这种情况下,this指代window。

  1. var obj = {
  2. value: 'hi',
  3. printThis: function() {
  4. console.log(this);
  5. }
  6. };
  7. var print = obj.printThis;
  8. print();

严格模式下,是undefined。

(5) 构造函数
this 执行当前类的实例

  1. class obj {
  2. value;
  3. constructor() {
  4. this.value = 5;
  5. console.log(this);
  6. }
  7. }
  8. var a = new obj();

(6)箭头函数
因为箭头函数没有this,所以在箭头函数里面的this是它外层作用域里面的非箭头函数的this。

  1. const obj= value => {
  2. console.log(this);
  3. }
  4. obj();
  1. var A = {
  2. name: 'A',
  3. sayHello: function(){
  4. var s = () => console.log(this)
  5. return s
  6. }
  7. }
  8. var sayHello = A.sayHello();
  9. sayHello();

测试题一:

  1. var obj = {
  2. value: 'hi',
  3. printThis: function() {
  4. console.log(this);
  5. }
  6. };
  7. var print = obj.printThis;
  8. obj.printThis();
  9. print();

会打印出什么?

测试题二:

  1. var obj1 = {
  2. value: 'hi',
  3. print: function() {
  4. console.log(this);
  5. },
  6. };
  7. new obj1.print();

会打印出什么?
测试题三

  1. const obj = {
  2. num: 10,
  3. hello: function () {
  4. console.log(this);
  5. setTimeout(() =>{
  6. console.log(this);
  7. });
  8. }
  9. }
  10. obj.hello();

会打印出什么?

额外说一下call\apply\bind
这三个函数的存在意义是什么?就是改变函数运行时的this指向。
call、apply与bind的差别
call和apply改变了函数的this上下文后便执行该函数,而bind则是返回改变了上下文后的一个函数。
call、apply的区别
他们俩之间的差别在于参数的区别,call和aplly的第一个参数都是要改变上下文的对象,而call从第二个参数开始以参数列表的形式展现,apply则是把除了改变上下文对象的参数放在一个数组里面作为它的第二个参数。

实际应用:

  • 求数组中的最大和最小值
    1. var arr = [34,5,3,6,54,6,-67,5,7,6,-8,687];
    2. Math.max.apply(Math, arr);
    3. Math.max.call(Math, 34,5,3,6,54,6,-67,5,7,6,-8,687);
    4. Math.min.apply(Math, arr);
    5. Math.min.call(Math, 34,5,3,6,54,6,-67,5,7,6,-8,687);