首页/文章/javascript

this指向-箭头函数this指向详解

2023-12-19
10934 分钟
...

一、思考:

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

console.log(this === window);   

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

    function test() {
      console.log(this===window);  
    }
    test();

2、隐式绑定规则

理解:谁调用就指向谁

1.对象内调用方法

    let obj = {
      name: 'obj',
      foo: function () {
        console.log(this);   
      }
    }
    obj.foo()

2.修改一下:

    let obj = {
      name: 'obj',
      foo: function () {
        console.log(this);    
        function test() {
          console.log(this);  
        }
        test()
      }
    }
    obj.foo()

3.隐式丢失:

    let obj = {
      name: 'obj',
      foo: function () {
        console.log(this);  
      }
    }
    let bar = obj.foo
    bar()

4.函数作为参数:

    function foo() {
      console.log(this);  
    }
    function bar(fn) {
      fn()
    }
    let obj = {
      name: 'obj',
      foo: foo
    }
    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,我们只能这样:

    var a = 0
    function foo() {
      let that = this   
      console.log(this);
      function test() {
      console.log(that)  
       
      }
      test()
    }
    let obj = {
      a: 1,
      foo: foo
    }
    obj.foo()

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

    var a = 0
    function foo() {
      console.log(this);  
      function test() {
        console.log(this);
      }
      test.call(obj)
    }
    let obj = {
      a: 1,
      foo: foo
    }
    obj.foo()

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

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

    var a = 0
    function foo() {
      let test = () => {
        console.log(this)
      }
      return test
    }
    let obj = { a: 1, foo: foo }
    obj.foo()()
   

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

    let a = 0
    let obj1 = {
      a: 1,
      foo: () => {
        console.log(this);
      }
    }
    obj1.foo() 

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

    var a = 0
    function foo() {
      let test = () => {
        console.log(this)
      }
      return test
    }
    let obj1 = {
      a: 1,
      foo: foo
    }
    let obj2 = {
      a: 2,
      foo: foo
    }
    obj1.foo().call(obj2)

     

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
javascript2025-09-18
JavaScript 的多线程能力:Worker
如果你写过一些计算量稍大的 JavaScript 代码,比如图像处理、大量数据排序或者复杂的算法,你几乎肯定遇到过浏览器“卡死”的现象。点击页面没反应,动画也停了,就像整个世界都静止了。 这就是主线程被阻塞的典型后果。因为主线程既要负责执行 JavaScript,又要负责渲染页面、响应用户操作,一旦它被繁重的计算任务占满,就无暇顾及其他,用户体验便直线下降。 这个问题的根源,正是“主线程是单线程的”。那么,如何解决呢? 答案很简单:把这...
学习面试
javascript2025-09-10
手把手教你实现一个EventEmitter
你是不是也遇到过这种情况:代码里各种事件监听和触发,回调函数套了一层又一层,最后自己都理不清哪个事件先触发、哪个后触发了? 别担心,今天我就带你从零开始实现一个自己的事件触发器(EventEmitter),让你彻底掌握事件驱动的精髓,代码清晰度直接提升200%! 为什么要懂EventEmitter? 先说说为什么我们要关心这个。Node.js的核心就是事件驱动,比如文件读写、网络请求,都是通过事件来处理的。不会EventEmitter,...
学习面试
javascript2025-08-09
Web Worker 多线程魔法
你是否曾遇到过网页因为复杂计算而卡顿的情况?今天,让我们一起探索Web Worker的神奇世界,看看如何用多线程技术解决性能瓶颈,并实现流畅的图片压缩功能! 为什么需要Web Worker? 想象一下,你在一个繁忙的餐厅里,只有一位服务员(主线程)负责点餐、上菜、结账所有工作。当客人突然暴增时,这位服务员就会手忙脚乱,其他客人只能干等着… 这就是JavaScript的现状—— 单线程 !所有任务都在一个线程中排队执行,一旦遇到复杂计算(...
学习面试
javascript2025-08-07
🌐AST抽象语法树
AST 是前端开发中一个非常重要的概念,它就像是代码的“编译器”,能够帮助我们理解和操作代码。本文将深入探讨 AST 的原理和应用,带你从零开始了解 AST。 一、什么是 AST? AST(抽象语法树)是一种树形结构,用于表示程序代码的语法结构。它将代码分解为一系列的节点,每个节点代表代码中的一个元素,如变量、函数、表达式等。AST 是编译器和解释器的基础,也是代码分析和转换的关键工具。 1\. AST 的结构 AST 的结构通常包括以...
学习面试
javascript2025-08-05
打字机效果是如何实现的
分析效果 使用 AI 对话的时候,文字是一个字一个字蹦出来的?它不是等所有内容生成完毕后一次性展示,而是以一种流畅、实时的“打字机”效果呈现,这种体验的背后,隐藏着一种高效的Web技术。它就是 服务器推送事件(Server Sent Events,简称 SSE) 什么是 SSE 从根本上说,SSE 是一种允许服务器 单向 、 持续 地向客户端(浏览器)推送数据的Web技术。 可以把它想象成一个 电台广播 : 服务器 是广播电台,持续不断...
学习面试
javascript2025-08-04
Promise 从原理到实现
前言 是 异步编程的核心概念之一,它为我们提供了一种更优雅的方式来处理异步操作。 本文将全面剖析 的工作原理,并逐步实现一个符合 规范的 。 正文 一、Promise 基础概念 代表一个异步操作的最终完成(或失败)及其结果值。它有 种状态: 1. pending : ,既不是成功,也不是失败状态 2. fulfilled :意味着操作 完成 3. rejected :意味着操作 状态一旦改变就不能再变,只能从 变为 ,或从 变为 。 二...
学习面试

评论

请登录后发表评论

去登录
加载评论中...

目录