一、思考:

1.为什么不能使用箭头函数来定义methods?

答:因为箭头函数没有自己的作用域,绑定的是父级作用域的上下文,

如果使用箭头函数,那么在获取data里面的数据的时候,this指向window导致访问失败

原因:这跟this的绑定规则有关,在箭头函数中不绑定this,但是如果箭头函数使用了this,会往上层作用域去找,注意:methods对象并不是作用域(所有的对象都没有作用域)

2.不使用箭头函数的情况下,this到底指向什么?

答:vue源码通过bind显式绑定指向vue实例的proxy(代理)

二、this指向:

首先,我们必须先知道,每个函数都会有自身的this,但是this并不是在函数声明完就绑定到某个对象上的,只有在函数调用时,this才会被绑定,

也就是说,this的绑定和函数定义的位置没有关系,和函数的调用方式有关系。

常见的this指向:

  • 全局作用域中或者普通函数中this指向全局对象window
  • 立即执行函数this必定指向window
  • 定时器this指向window
  • 事件中this指向事件源对象
  • 方法中谁调用就指向谁
  • 构造函数中this指向对象实例

三、this绑定规则:

1、默认绑定规则

1.默认绑定全局对象window

 1console.log(this === window);   

2.全局作用域下独立调用函数,this指向window

 1    function test() {
 2      console.log(this===window);  
 3    }
 4    test();

2、隐式绑定规则

理解:谁调用就指向谁

1.对象内调用方法

 1    let obj = {
 2      name: 'obj',
 3      foo: function () {
 4        console.log(this);   
 5      }
 6    }
 7    obj.foo()

2.修改一下:

 1    let obj = {
 2      name: 'obj',
 3      foo: function () {
 4        console.log(this);    
 5        function test() {
 6          console.log(this);  
 7        }
 8        test()
 9      }
10    }
11    obj.foo()

3.隐式丢失:

 1    let obj = {
 2      name: 'obj',
 3      foo: function () {
 4        console.log(this);  
 5      }
 6    }
 7    let bar = obj.foo
 8    bar()

4.函数作为参数:

 1    function foo() {
 2      console.log(this);  
 3    }
 4    function bar(fn) {
 5      fn()
 6    }
 7    let obj = {
 8      name: 'obj',
 9      foo: foo
10    }
11    bar(obj.foo)

4.1函数作为参数时,参数函数叫做子函数,外面的函数叫父函数,子函数也叫回调函数,像这样的函数有很多,

比如forEach 、setimeout,这些函数里的参数函数也叫内置参数

记住:父函数有能力决定子函数this的指向,例如forEach里第一个参数是一个函数,第二个参数就是this绑定的对象,不写默认绑定window

3、显式绑定

call、apply、bind bind返回一个新函数,新函数指向绑定的对象,旧函数不会

4、new绑定

this指向函数实例化之后的对象

5、绑定规则优先级:

new绑定 > 显式绑定 > 隐式绑定 > 默认绑定

四、箭头函数this指向问题:

1.箭头函数没有自己的this指向,它的this指向上一级作用域的this

1.1之前,我们想让内部函数的this指向外部函数的this,我们只能这样:

 1    var a = 0
 2    function foo() {
 3      let that = this   
 4      console.log(this);
 5      function test() {
 6      console.log(that)  
 7       
 8      }
 9      test()
10    }
11    let obj = {
12      a: 1,
13      foo: foo
14    }
15    obj.foo()

1.2或者使用bind/call/apply显式绑定外部函数的this:

 1    var a = 0
 2    function foo() {
 3      console.log(this);  
 4      function test() {
 5        console.log(this);
 6      }
 7      test.call(obj)
 8    }
 9    let obj = {
10      a: 1,
11      foo: foo
12    }
13    obj.foo()

2.箭头函数this指向不遵循上述的四种规则:

2.1独立调用对箭头函数无效:

 1    var a = 0
 2    function foo() {
 3      let test = () => {
 4        console.log(this)
 5      }
 6      return test
 7    }
 8    let obj = { a: 1, foo: foo }
 9    obj.foo()()
10   

隐式绑定对箭头函数无效:

 1    let a = 0
 2    let obj1 = {
 3      a: 1,
 4      foo: () => {
 5        console.log(this);
 6      }
 7    }
 8    obj1.foo() 

2.3显式绑定对箭头函数无效:

 1    var a = 0
 2    function foo() {
 3      let test = () => {
 4        console.log(this)
 5      }
 6      return test
 7    }
 8    let obj1 = {
 9      a: 1,
10      foo: foo
11    }
12    let obj2 = {
13      a: 2,
14      foo: foo
15    }
16    obj1.foo().call(obj2)
17
18     
个人笔记记录 2021 ~ 2025