san.js源码解读之模版解析(parseTemplate)篇——readAccessor函数

相关文章:san.js源码解读之模版解析(parseTemplate)篇——readIdent函数

一、源码分析

/**
 * 读取访问表达式
 *
 * @param {Walker} walker 源码读取对象
 * @return {Object}
 */
function readAccessor(walker) {
    var firstSeg = readIdent(walker);

    switch (firstSeg) { // 判断标识符
        case 'true':
        case 'false':
            return { // 遇到布尔值直接返回
                type: ExprType.BOOL,
                value: firstSeg === 'true', // 和字符串 'true' 直接判断返回布尔值
            };
        case 'null':
            return {
                type: ExprType.NULL
            };
    }

    var result = {
        type: ExprType.ACCESSOR, // 当前类型
        paths: [
            {type: ExprType.STRING, value: firstSeg}
        ]
    };

    /* eslint-disable no-constant-condition */

    // 对象访问有两种形式
    // 1: 点符号 - 在JavaScript中访问对象属性的一种常见方式是通过点符号。这涉及到在对象名称之后指定属性名称,两者之间用一个点隔开。
    // 例如:const name = {
    //   firstName: "Surbhi",
    //   lastName: "Dighe
    //  };
    // console.log(name.firstName);  // Output: "Surbhi"
    // 2: 括号符号 - 另一种访问对象属性的方法是通过括号符号,这涉及到将属性名称指定为方括号内的字符串
    // 例如:console.log(name["firstName"]);  // Output: "Surbhi"
    accessorLoop: while (1) {
    /* eslint-enable no-constant-condition */

        switch (walker.source.charCodeAt(walker.index)) {
            case 46: // .    当遇到 '.' 说明变量访问是 'person.job' 或者 'person[1].job' 之类的变量访问
                 walker.index++; // 向前移动,移过 '.'

                // ident as string
                // 因为遇到了 '.' 说明下面一定是一个变量名,所以使用 readIdent 进行解析
                result.paths.push({
                    type: ExprType.STRING,
                    value: readIdent(walker)
                });
                break;

            case 91: // [  当遇到 '[' 说明当前正处于 'person[]'
                walker.index++; // 向前移动,移过 '['
                result.paths.push(readTertiaryExpr(walker)); // 调用 readTertiaryExpr 进行匹配, 这是因为 '[]' 中可以有其他表达式,比如 'person[ index === 1 ? 1 : 0]' 或者 'person[name]'
                walker.goUntil(93); // ]
                break;

            default:
                break accessorLoop; // 默认跳出循环
        }
    }

    return result; // 返回匹配结果
}

在 javascript 中访问对象属性有两种方法分别如下
1: 点符号 - 在JavaScript中访问对象属性的一种常见方式是通过点符号。这涉及到在对象名称之后指定属性名称,两者之间用一个点隔开。
例如:

 		   const name = {
 		    firstName: "Surbhi",
 		    lastName: "Dighe
 		    };	
 	    	console.log(name.firstName);  // Output: "Surbhi"

2: 括号符号 - 另一种访问对象属性的方法是通过括号符号,这涉及到将属性名称指定为方括号内的字符串
例如:
console.log(name["firstName"]); // Output: "Surbhi"
在 readAccessor 中对属性访问的处理也是分这两种情况(但是需要了解的是‘person’单独变量在 readAccessor 函数中也是可以解析的,作为访问表达式,这也为什么readAccessor 函数的功能叫做读取访问表达式,而不是读取对象属性)。

首先通过 readIdent 函数解析出当前变量名,对变量名进行匹配如下

switch (firstSeg) { // 判断标识符
        case 'true':
        case 'false':
            return { // 遇到布尔值直接返回
                type: ExprType.BOOL,
                value: firstSeg === 'true', // 和字符串 'true' 直接判断返回布尔值
            };
        case 'null':
            return {
                type: ExprType.NULL
            };
    }

如果符合 ‘true’ 、‘false’和’null’,那么直接返回,后续不执行。那么什么时候遇到这种情况呐?比如 三元表达式时,匹配到‘true’或者‘false’就会走入该条件判断。

接着定义了访问符类型, 并且记录当前位置(value)

var result = {
      type: ExprType.ACCESSOR, // 当前类型
      paths: [
          {type: ExprType.STRING, value: firstSeg}
      ]
  };

然后对当前访问表达式进行循环匹配,当遇到 ‘.’ 时,说明是‘demo.job’ 这种情况,那么执行下面语句

case 46: // .    当遇到 '.' 说明变量访问是 'person.job' 或者 'person[1].job' 之类的变量访问
   walker.index++; // 向前移动,移过 '.'

   // ident as string
   // 因为遇到了 '.' 说明下面一定是一个变量名,所以使用 readIdent 进行解析
   result.paths.push({
       type: ExprType.STRING,
       value: readIdent(walker)
   });
   break;

当遇到‘[’时,说明是’demo[job]'、‘demo[index ? 1: 0]’ 、‘demo[‘true’]’等情况,那么执行面的语句

case 91: // [  当遇到 '[' 说明当前正处于 'person[]'
     walker.index++; // 向前移动,移过 '['
     result.paths.push(readTertiaryExpr(walker)); // 调用 readTertiaryExpr 进行匹配, 这是因为 '[]' 中可以有其他表达式,比如 'person[ index === 1 ? 1 : 0]' 或者 'person[name]'
     walker.goUntil(93); // ]
     break;

这里需要了解的是向 paths 数组中推入数据时调用了 readTertiaryExpr ,这是因为在‘[]’中可能有复杂的表达式,里面有变量数值等逻辑,所以需要从头解析。对于 readTertiaryExpr 函数内容后续会有介绍(解析表达式有点复杂,而且牵涉到嵌套、递归、解析先后顺序等逻辑)

当没有遇到‘.’或者‘[’, 那么走默认逻辑,直接跳出循环

default:
   break accessorLoop; // 默认跳出循环

二、示例: ‘person.job.one’

解析 ‘person.job.one’ 的结果
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/109332.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud 微服务全栈体系(九)

第九章 Docker 三、Dockerfile 自定义镜像 常见的镜像在 DockerHub 就能找到,但是我们自己写的项目就必须自己构建镜像了。 而要自定义镜像,就必须先了解镜像的结构才行。 1. 镜像结构 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而…

百货中心供应链管理系统

毕业设计说明书 百货中心供应链管理系统 百货中心供应链管理系统 摘要 近年来,随着计算机技术的发展,以及信息化时代下企业对效率的需求,计算机技术与通信技术已经被越来越多地应用到各行各业中去。百货中心作为物流产业链中重要的一环&a…

基于Qt 文本读写(QFile/QTextStream/QDataStream)实现

​ 在很多时候我们需要读写文本文件进行读写,比如写个 Mp3 音乐播放器需要读 Mp3 歌词里的文本,比如修改了一个 txt 文件后保存,就需要对这个文件进行读写操作。本章介绍简单的文本文件读写,内容精简,让大家了解文本读写的基本操作。 ## QFile 读写文本 QFile 类提供了读…

基于机器视觉的二维码识别检测 - opencv 二维码 识别检测 机器视觉 计算机竞赛

文章目录 0 简介1 二维码检测2 算法实现流程3 特征提取4 特征分类5 后处理6 代码实现5 最后 0 简介 🔥 优质竞赛项目系列,今天要分享的是 基于机器学习的二维码识别检测 - opencv 二维码 识别检测 机器视觉 该项目较为新颖,适合作为竞赛课…

07. 蜂鸣器

07. 蜂鸣器 硬件原理分析代码编写 硬件原理分析 此处为PNP型三极管,BEEP为低的时候三极管才会导通,也就是BEEP0时,蜂鸣器会叫。BEEP是通过SNVS_TAMPER1这个IO控制的 代码编写 将前面的bsp、imx6ul、obj和project拷贝过来 初始化SNVS_TAMPE…

MSQL系列(十) Mysql实战-Join驱动表和被驱动表区分

Mysql实战-Join驱动表和被驱动表区分 前面我们讲解了Mysql的查询连接Join的算法原理, 我发现大家都知道小表驱动大表,要让小表作为驱动表, 现在有2个问题 查询多表, 到底哪个是驱动表?哪个是被驱动表, 如何区分?索引如何优化,到底是加在驱动表上,还是被驱动表上? 今天我们…

40基于MATLAB,使用模板匹配法实现车牌的识别。

基于MATLAB,使用模板匹配法实现车牌的识别。具体包括将原图灰度化,边缘检测,腐蚀操作,车牌区域定位,车牌区域矫正,二值化,均值滤波,切割,字符匹配,最终显示车…

codeforces (C++ Doremy‘s Paint 3)

题目: 翻译: 思路: 1、题目意思:将数组中的数进行排列,任意相邻两个数的和都相等,才能说这个数组为好。一下分三种情况讨论。 2、当数组中有三种及三种以上的数字,那任意相邻两个数的和都相等必…

智慧停车视频解决方案:如何让AI助力停车管理升级?

一、项目背景 停车场的管理区域由于面积比较大,进出车辆多,所以在保安方面决不能有任何的麻痹和松懈,继续采用过去保安方式已远远不能满足现代安全防范的需求。为满足停车场的安全和科学系统化管理的需要,以及为了对随时发生的情…

精品Python的定制化图书借阅推荐引擎设计与实现

《[含文档PPT源码等]精品基于Python的定制化图书推荐引擎设计与实现》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功! 软件开发环境及开发工具: 开发语言:python 使用框架:Django 前端技…

【持续交付】个人网站

今天给大家演示下如何基于Vuepress尝试持续交付博客网站。 也尝试过其他的方案,比如使用Typora导出html文件,并scp该文件到服务器上。 效果图 该持续交付主流程如下图 提交代码后会触发webHook生成version.txt,部署脚本每分钟轮询一次检测是否存在vers…

物联网和互联网医院小程序:如何实现医疗设备的远程监测和管理?

物联网(IoT)技术的发展为医疗设备的远程监测和管理提供了巨大的机会。结合互联网医院小程序,我们可以实现对医疗设备的远程访问、监控和管理,从而提高医疗服务的质量和效率。本文将介绍如何实现医疗设备的远程监测和管理&#xff…

漏洞复现-dedecms文件上传(CVE-2019-8933)

dedecms文件上传_CVE-2019-8933 漏洞信息 Desdev DedeCMS 5.7SP2版本中存在安全漏洞CVE-2019-8933文件上传漏洞 描述 ​ Desdev DedeCMS(织梦内容管理系统)是中国卓卓网络(Desdev)公司的一套基于PHP的开源内容管理系统&#x…

磁盘调度算法之先来先服务(FCFS),最短寻找时间优先(SSTF),扫描算法(SCAN,电梯算法),LOOK调度算法

目录 1.一次磁盘读/写操作需要的时间1.寻找时间2.延迟时间3.传输时间4.影响读写操作的因素 2.磁盘调度算法1.先来先服务(FCFS)1.例题2.优缺点 2.最短寻找时间优先(SSTF)1.例题2.优缺点3.饥饿的原因 3.扫描算法(SCAN)1.例题2.优缺点 4.LOOK调度算法1.例题2.优点 5.循环扫描算法(…

JDK8新特性:Stream流

目录 1.获取Stream流 2.Stream流常见的中间方法 3.Stream流常见的终结方法 1、 Stream 是什么?有什么作用?结合了什么技术? ●也叫 Stream 流,是Jdk8开始新增的一套 API ( java . util . stream .*),可以用于操作集…

SpringCloud 微服务全栈体系(七)

第九章 Docker 一、什么是 Docker 微服务虽然具备各种各样的优势,但服务的拆分通用给部署带来了很大的麻烦。 分布式系统中,依赖的组件非常多,不同组件之间部署时往往会产生一些冲突。在数百上千台服务中重复部署,环境不一定一致…

【ICCV2023】频率成分在少样本学习中的重要性

论文标题:Frequency Guidance Matters in Few-Shot Learning 论文链接:https://openaccess.thecvf.com/content/ICCV2023/html/Cheng_Frequency_Guidance_Matters_in_Few-Shot_Learning_ICCV_2023_paper.html 代码:暂未开源 引用:…

入学生活科研随笔

近而立之年,巅峰享受的时期有两段。一是高考后,收到入学通知书。早晨,八点多,我醒来在院子里看到,爸爸在门口和邮政快递员寒暄。那天应该是8月15号,清晨凉凉爽爽的,杨树遮住了大半个院子。第二段…

2-多媒体数据压缩国际标准-Part3

文章目录 视频压缩的国际标准MPEG-1&MPEG-2/H.262视频标准MPEG-4 AVC/H.264视频标准H.264编码框架概述H.264视频编码的技术创新点 H.265/HEVC视频标准HEVC性能与编解码框架概述Quadtree-based coding structureDeblocking & SAO FilterHEVC各模块运算量 视频压缩的国际…

利用Web Serial API实现Vue与单片机串口通信

一、Web Serial API介绍 Web Serial API 是一项 Web 技术,用于在浏览器中访问串行端口设备(如 Arduino、传感器等)并与之通信。它提供了一组 JavaScript 接口,使得 Web 应用程序可以通过 USB 串行端口连接到硬件设备&…