IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 【经典面试题】作用域链 与 函数中的this指向 -> 正文阅读

[JavaScript知识库]【经典面试题】作用域链 与 函数中的this指向

下列函数中 this 的指向 :

        let obj = {
            name:'张三',
            age:18,
            sayHi(){
                let fn1 = function(){
                    console.log(this)
                }
                fn1()

                let fn2 = ()=>{
                    console.log(this)
                }
                fn2()
            },
            eat:()=>{
                let fn3 = function(){
                    console.log(this)
                }
                fn3()
                
                let fn4 = ()=>{
                    console.log(this)
                }
                
                fn4()
            }
        }
        obj.sayHi()
        obj.eat()

解题辅助知识点

1 . 作用域

变量作用域 : 变量起作用的范围

  1. 全局作用域(全局变量) :在函数外外面声明,页面任何地方都可以使用
  2. 局部作用域(局部变量) : 在函数内部声明,只能在函数内部使用
  3. 块级作用域 : 在大括号里面声明的变量(分支和循环),只能在大括号内部使用
      //1.全局变量 :   全局作用域
      let num = 10

      function fn () {//函数的形参相当于在函数内部声明变量 : 局部变量
        //2.局部变量: 局部作用域(函数内部作用域)
        let age = 30
        console.log(age)
      }
      fn()

      for (let i = 1; i <= 10; i++) {
          //3.块级变量:块级作用域(只能在大括号内部使用)
        console.log(i)
      }

2 . 作用域链

原理 : 默认情况下,js代码处于全局作用域(0级),当我们声明一个函数的时候,就会开辟一个局部作用域. 函数里面也可以声明函数,就会又形成局部作用域(2级),以此类推就会形成作用域链

      //全局作用域(0级)
      let num = 10

      function fn () {
        //局部作用域(1级)
        let num = 20
        console.log('1级作用域' + num)//20

        function fn1 () {
          //局部作用域(2级)
          let num = 30
          console.log('2级作用域' + num)//30
        }
        fn1()
      }

      fn()

      console.log('0级作用域' + num)//10

变量在作用域链中的访问规则:就近原则

  • 当你在某个作用域访问变量的时候,会先看当前作用域有没有声明。如果有则访问当前作用域的变量。没有就找上级,上级也没有就继续往上。直到作用域最顶端(0级),如果0级也没有,则程序会报错。 xxx is not defined

3 . 函数中的this指向

function函数this指向: 谁‘调用’我,我就指向谁 (取决于调用,与声明无关)

  1. 普通函数 : 函数名() this 指向 window
  2. 对象方法 : 对象名.方法名() this 指向对象
  3. 构造函数 : new 函数名() this 指向 new 创建的实例对象

箭头函数中的this : 谁‘声明’我,我就指向谁

  • 真正的含义 : 箭头函数没有this
  • 箭头函数本身是没有this的,本质是通过作用域链,访问上一级的this
      //0级作用域链
      //1.普通函数
      let fn = () => {                                                                   
        //1级作用域链
        console.log(this)
      }
      fn() //window

      //2.对象的方法
      let obj = {
        name: '张三',
        age: 20,
        eat () {//function(){}
          //1级作用域链
          console.log(this)//obj
          let fn = () => {
            //2级作用域链
            console.log(this)//obj
          }
          fn()
        },
        learn: () => {
          //1级作用域链 : this访问0级
          console.log(this)//window
        }
      }
      obj.eat() //obj  function函数的this取决于调用
      obj.learn() //window  箭头函数跟调用没关系,永远都是访问上级作用域this

解题思路

  1. sayHi() 是对象的方法, 在1级作用域链, this 指向 obj
  2. f1() 在2级作用域链, 但是 function 函数取决于调用, fn1()这是普通函数调用, this 指向 window
  3. fn2 = ()=>{} 在2级作用域链, 箭头函数访问上级作用域也就是 sayHi() , this 指向 obj
  4. eat:()=>{} 在1级作用域链,但是尖头函数访问上一级作用域0级, this 指向 window
  5. fn3 = function(){} 在2级作用域链, function 函数取决于调用, fn3()这是普通函数调用, this 指向 window
  6. fn4 = ()=>{} 在2级作用域链, 箭头函数访问上级作用域也就是 eat:()=>{} , this 指向 window
        let obj = {
            name:'张三',
            age:18,
            sayHi(){
                //1级链   this:  obj

                let fn1 = function(){
                    //2级链 ; function函数取决于调用  fn1()这是普通函数调用
                    console.log(this)//window
                }
                fn1()

                let fn2 = ()=>{
                    //2级链 :  箭头函数访问上级  1级this -> obj
                    console.log(this)//obj
                }
                fn2()
            },
            eat:()=>{
                //1级链  this:window
                let fn3 = function(){
                    //2级链  function函数取决于调用  fn3()这是普通函数调用
                    console.log(this)//window
                }
                fn3()

                let fn4 = ()=>{
                    //2级链:  箭头函数访问上级  1级this -> window
                    console.log(this)//window
                }
                
                fn4()
            }
        }
        obj.sayHi()
        obj.eat()

答案 :

f1 : window 
f2 : obj
f3 : window
f4 : window
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-07 13:38:22  更:2022-02-07 13:38:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:22:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码