This | 青训营笔记

39 阅读2分钟

平时开发过程中,虽然都是用hooks或者composition api,但是this在JS中还是非常重要的东西,并且其规则也是容易混淆。

1. 普通函数

解析器在调用函数时每次都会向函数内部传递进一个隐含的参数 这个隐含的参数就是this,this指向的是一个对象 这个对象是函数执行的上下文对象,调用该函数的上下文对象 根据函数的调用方式的不同,this会指向不同的对象

  • 以函数的形式调用时,this指向的是window
  • 以方法的形式调用时,this指向的是调用方法的那个对象
    window.color='red'
    let obj = {
        color:'blue',
        sayColor:sayColor
    }
    function sayColor(){
        console.log(this.color)
    }
    sayColor();			//'red'
    obj.sayColor		//'blue'
    function Obj() {
        a = 1
        fun = function() {
            console.log(this)
        }
        console.log(this)   //obj
        fun()   //window
    }
    const obj = new Obj()

2. 箭头函数

在箭头函数中,this指向的是定义箭头函数的上下文 当事件回调或定时回调中调用某个函数时,this指向的并非想要的对象, 这时就可以将回调函数写成箭头函数便可解决问题。比如定时器 setTimeout

    window.color = 'red'
    let sayColor = () => console.log(this.color)
    let obj = {
        color: 'blue',
        sayColor:sayColor
    }
    sayColor();	//'red'
    obj.sayColor();	//'red'
    function Obj() {
        a = 1
        fun = () => {
            console.log(this)
        }
        console.log(this)  //obj
        fun()   //obj
    }
    const obj = new Obj()

题目1

var name = "window";
var person = {
  name: "person",
  sayName: function () {
    console.log(this.name);
  }
};
function sayName() {
  var sss = person.sayName;
  sss();		// window
  person.sayName();			//person
  (person.sayName)();   	//person
  (b = person.sayName)();			//window
}
sayName();

这个主要是(person.sayName)()(b = person.sayName)() (person.sayName)()在解析过程中就是拿到sayName方法调用,所以结果就是person

(b = person.sayName)()由于有一个赋值表达式,所以等价于

(b = person.sayName)()

// 等价于⬇

b = person.sayName
b()

作为独立函数调用,所以this指向window

题目2

var name = 'window'
function Person (name) {
  this.name = name
  this.obj = {
    name: 'obj',
    foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () => {
        console.log(this.name)
      }
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')

person1.obj.foo1()()		// window
person1.obj.foo1.call(person2)()    // window
person1.obj.foo1().call(person2)    // person2

person1.obj.foo2()()		// obj
person1.obj.foo2.call(person2)()    // person2
person1.obj.foo2().call(person2)    // obj

就是注意一下箭头函数是不绑定this的,会去上层作用域去寻找this,所以这里面调用foo2的函数得到的箭头函数都是指向foo2的this值。