浅谈 JS 中的 This 指向

108 阅读1分钟

确定this值的4种途径

  1. 查看MDN文档
  2. 查看浏览器源码(C++)或库源码
  3. 看函数调用(不能看函数声明)
  4. console.log(this)

重复一遍:想确定this的值不能看函数声明 函数的5种调用方式

  1. fn(参数1)
  2. obj.x.method(参数1)
  3. fn.call(神秘参数,参数1)
  4. fn.apply(神秘参数,[参数1])
  5. new fn(参数1)

如何知道this指向谁? 将所有调用改成call或apply

  1. fn(参数1)---> fn.call(undefined,参数1)
  2. obj.x.method(参数1) ---> obj.x.method.call(obj.x,参数1)

总结 通过调用确定this的值 第一步:记下每种调用形式的this或将调用转为call形式 第二步:将this替换为有意义的变量名 例子1:

function f () {
  console.log(this)
}
f()
// 这是一个简单的函数调用,这样的函数调用其实是一个语法糖
// 实际可以写成 f() ==== f.call(undefind) 在浏览器中会自动把 undefind 指向 Window this 当然指向 Window
// 我们来实验看下下面的this指向哪里?
var length = 4;
function callback() {
console.log(this.length); // => 打印出什么?
}
const obj = {
length: 5,
method(callback) {
callback();  // 直接看哪里调用了 this 转换成 callback() === callback.call(undefind) => length === 4
}
};
obj.method(callback, 1, 2); // 这里很复杂

例子2:

const obj = {
  name:'obj',
  fn(){
    console.log('this:'+this.name)
 }
  
}
obj.fn() // 第一次打印
const fn = obj.fn;fn();// 第二次打印
[obj.fn][0]() // 第三次打印
let f;(f = obj.fn)() // 第四次打印

例子3:

var name = 1;
function test() {
  let name = 2
  let obj = {
    name: 3,
    fn: () => {
      var name = 4
      console.log(this.name)
    }
  }
  return obj;
}
test().fn()

/* 
 test().fn()
 obj.fn()
 fn.call(obj)
 因为 fn是箭头函数,即fn没有this
 fn又在全局里调用,所以找到this === window
*/