当前位置: 首页 > article >正文

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

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

一、源码分析

/**
 * 读取调用
 *
 * @param {Walker} walker 源码读取对象
 * @param {Array=} defaultArgs 默认参数
 * @return {Object}
 */
function readCall(walker, defaultArgs) {
    walker.goUntil(); // 向前读取字符,直到遇到指定字符再停止
    var result = readAccessor(walker); // 读取访问表达式

    var args;
    if (walker.goUntil(40)) { // (   判断是否遇到 '(', 如果遇到进入下面处理
        args = [];

        while (!walker.goUntil(41)) { // ) 判断是否遇到')',它是跳出循环的判断条件
            args.push(readTertiaryExpr(walker)); // 因为在处理函数调用时,会遇到复杂的表达式,所以调用 readTertiaryExpr 函数来处理出现所以表达式的可能
            walker.goUntil(44); // ,
        }
    }
    else if (defaultArgs) {
        args = defaultArgs; // 如果有默认参数时,直接赋值 args。这里比较好理解,因为上面的操作就是解析函数参数的。
    }

    if (args) {
        result = {
            type: ExprType.CALL,
            name: result, // 把之前解析到的访问表达式,放入对象中并起名 name
            args: args
        };
    }

    return result; // 返回结果
}

在 san.js 中 readCall 函数是用来解析函数调用的。比如

<p>{{max(num1, num2)}}</p>

readCall 函数接收两个参数:walker 和 defaultArgs。

  1. walker 是 Walk 类的实例,它是源码读取对象
  2. defaultArgs 是默认参数,就是调用函数是传入的参数。比如 max(num1, num2) 中的 ’num1‘ 和 ‘num2’

当执行 readCall 函数时,首先执行 goUntil() 函数用来跳过空格、制表符、\r、\n之类的。goUntil 函数源码如下

/**
 * 向前读取字符,直到遇到指定字符再停止
 * 未指定字符时,当遇到第一个非空格、制表符的字符停止
 *
 * @param {number=} charCode 指定字符的code
 * @return {boolean} 当指定字符时,返回是否碰到指定的字符
 */
Walker.prototype.goUntil = function (charCode) {
    var code;
    while (this.index < this.len && (code = this.source.charCodeAt(this.index))) {
        switch (code) {
            case 32: // 空格 space
            case 9: // 制表符 tab
            case 13: // \r
            case 10: // \n
                this.index++;
                break;

            default:
                if (code === charCode) {
                    this.index++;
                    return 1;
                }
                return;
        }
    }
};

可以看出 goUntil 接受一个变量 charCode, 当传入该变量时或判断当前字符是否为传入的字符,如果时就返回 1并跳出循环,否者跳出循环。
接着调用 readAccessor 函数获取当前访问表达式并返回结果,然后向下面判断是否遇到‘(’,如果遇到就开始匹配括号内的参数,代码如下

if (walker.goUntil(40)) { // (   判断是否遇到 '(', 如果遇到进入下面处理
       args = [];

       while (!walker.goUntil(41)) { // ) 判断是否遇到')',它是跳出循环的判断条件
           args.push(readTertiaryExpr(walker)); // 因为在处理函数调用时,会遇到复杂的表达式,所以调用 readTertiaryExpr 函数来处理出现所以表达式的可能
           walker.goUntil(44); // ,
       }
  }

如果没有遇到,接着判断有没有传入默认参数,有的话就直接把默认参数赋值给 args,最后返回属于调用函数类型的对象结果


http://www.kler.cn/news/108367.html

相关文章:

  • Python-自动化绘制股票价格通道线
  • 【Linux】:进程程序替换
  • IP应用场景API的反欺诈潜力:保护在线市场不受欺诈行为侵害
  • 《动手学深度学习 Pytorch版》 10.6 自注意力和位置编码
  • SQL注入原理及思路(mysql)
  • EASYX动画效果实现
  • 【网安AIGC专题10.19】论文6:Java漏洞自动修复+数据集 VJBench+大语言模型、APR技术+代码转换方法+LLM和DL-APR模型的挑战与机会
  • MAYA教程之模型的UV拆分与材质介绍
  • 黑豹程序员-架构师学习路线图-百科:API接口测试工具Postman
  • 8.循环神经网络
  • matlab中字符串转换为数字(str2double函数)
  • 【java爬虫】公司半年报数据展示
  • 明星艺人类的百度百科怎么创建 ?
  • Spring使用注解进行注入
  • 网络综合和简化实频理论学习概述
  • mysql查看数据表文件的存放路径
  • python—openpyxl操作excel详解
  • react中的函数柯里化
  • DWA算法,仿真转为C用于无人机避障
  • CleanMyMac X2024永久免费版mac电脑管家
  • Vue 项目中使用 Pinia 状态管理详细教程
  • 06、SpringCloud -- 订单详情界面实现
  • 阿里云服务器—ECS快速入门
  • 黑客技术(网络安全)—小白自学
  • Jupyter Notebook还有魔术命令?太好使了
  • 【解决方案】ubuntu 解决办法 ImportError: cannot import name ‘_gi‘ from ‘gi‘
  • 软路由安装code-server配置和配置Nodejs开发环境
  • Lvs+Nginx+NDS
  • 【实用网站分享】
  • css四种导入方式