js中this的指向,在不同的情况下,是不一样的,总是让人迷惑。
我们可以归类如下:

暴露在全局的this

在浏览器环境中this -> window对象; 在node中,this->global对象;

以下皆以全局对象表述

普通函数调用

  1. function foo() {
  2. console.log(this);
  3. }
  4. foo(); // 全局对象

做为对象的方法调用

  1. var obj = {
  2. name: 'simon',
  3. method: function() {
  4. console.log(this);
  5. },
  6. me: this
  7. }
  8. obj.method(); // 这里this指向obj
  9. console.log(obj.me); // 这里me指向全局对象

但是,obj.method被复制给一个变量,再去调用,this指向会改变:

var objMethod = obj.method;
objMethod(); // 这里的this又指向了全局对象

调用构造函数

function Foo(name) {
   this.name = name;
}
var newObj = new Foo(); // 这里的this指向新创建的对象newObj

(调用构造函数补充版)

/*首先由疑问而来,为何不同函数和构造函数的this指向不同??关键不在于函数,而在于new关键字*/
function Test(){
    this.mytest = true;
}
//Test自述:我看起来好像是一个类构造函数,但是我的根本还是function
Test()
window.mytest//true
//如果先执行构造函数
let t = new Test()
t.mytest//true
window.mytest//undefined
Test()
/*in a word 
new 调用构造函数的时候,操作符会生成一个新的空对象obj,默认将this的指向由window转为obj,人为return的话
也会改变this
*/
function Test(){
    this.mytest = true;
  let fake = {name:99};
  return fake
}
let m = new Test()
m.mytest//undefined
m.name//99

//当然如果非要单独执行下Test(),还是不会阻止window挂载的
Test()
window.mytest//true

callapplybind显示设置this

function bar(x, y) {
   console.log(this.a + x + y);
}
var obj = {a: 1, length: 1};
// 如下三个函数调用,this都指向了obj
bar.call(obj, 10, 20); // 31
bar.apply(obj, [10, 20]); // 31
bar.bind(obj, 10, 20)(); // 31

⚠️ 当使用 Function.prototype 上的 call 或者 apply 方法时,函数内的 this 将会被 显式设置为函数调用的第一个参数。

ES6里面的箭头函数

var obj = {
   name: 'simon',
   method: function() {
       function test() {
           console.log(this);
       }
       test(); // this指向全局对象
   }
};

修改this指向方法:

var obj = {
   name: 'simon',
   method: function() {
       var that = this;
       function test() {
           console.log(that);
       }
       test(); // that指向obj
   }
};

也可以用箭头函数:

const obj = {
   name: 'simon',
   method: function() {
       let test = () => {
           console.log(this);
       }
       test(); // this指向obj
   }
};

箭头函数,this指向固定化,并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,导致内部的this就是外层代码块的this。正是因为它没有this,所以也就不能用作构造函数

实例

1.  Array.prototype.sortNum = function () {
       return this.sort(function(a, b){
           return a>b;
       })    
   }    
   // 这里this的指向?
2.  function foo() {
       return function () {
           return function () {
               return function () {
                   console.log(this.id);
               }
           }
       }  
   }
   var f = foo.call({id: 1});
   f()()(); // ?
   f.call({id: 1})()() // ?
   f().call({id: 2})() // ?
   f()().call({id: 3}) // ?

3.  var user = {
       name: 'dk',
       methond: function() {
           console.log(this.name);
       }
   };
   function foo(fn) {
       fn();
   }
   foo(user.methond); // ?