string-template解析(梁王的代码解剖室)

项目地址

https://github.com/Matt-Esch/string-template

代码

var nargs = /\{([0-9a-zA-Z_]+)\}/g

module.exports = template

function template(string) {
    var args

    if (arguments.length === 2 && typeof arguments[1] === "object") {
        args = arguments[1]
    } else {
        args = new Array(arguments.length - 1)
        for (var i = 1; i < arguments.length; ++i) {
            args[i - 1] = arguments[i]
        }
    }

    if (!args || !args.hasOwnProperty) {
        args = {}
    }

    return string.replace(nargs, function replaceArg(match, i, index) {
        var result

        if (string[index - 1] === "{" &&
            string[index + match.length] === "}") {
            return i
        } else {
            result = args.hasOwnProperty(i) ? args[i] : null
            if (result === null || result === undefined) {
                return ""
            }

            return result
        }
    })
}

使用

template("{hoho} {keke} {haha}", {
  hoho: "what",
  keke: "the",
  haha: "f*ck"
})

分析

正则

var nargs = /\{([0-9a-zA-Z_]+)\}/g

这里顺便推荐一个正则练习和分析的网站regexr
这个正则比较简单,就是选择所有被大括号包裹着的数字字母下划线组合。用来选出类似{asd}的片段

核心

参数部分

代码里面接受3种(其实算2种)传参方式。
第一种是template(string, object) object里面包含替换的键值对。
第二种是template(string, array) array是一个数组,替换{0},{1}这种。
其实这两张方式的代码都是一样的,因为Array同时也是Object。直接放入args变量里面

if (arguments.length === 2 && typeof arguments[1] === "object") {
    args = arguments[1]
}

另一种是这样调用的

template("{0} {2} {1}", "asd","wanshe","tv")

第三种直接把后面的参数放入args里面

replace

string.replace(nargs, function replaceArg(match, i, index){...} )

String.replace后面可以接函数,具体的定义MDN有

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

Possible name Supplied value
match The matched substring. (Corresponds to $& above.)
p1, p2, ... The nth parenthesized submatch string, provided the first argument to replace() was a RegExp object. (Corresponds to $1, $2, etc. above.) For example, if /(\a+)(\b+)/, was given, p1 is the match for \a+, and p2 for \b+.
offset The offset of the matched substring within the whole string being examined. (For example, if the whole string was 'abcd', and the matched substring was 'bc', then this argument will be 1.)
string The whole string being examined.

这里使用的是function(match, p1, offset)

       if (string[index - 1] === "{" &&
            string[index + match.length] === "}") {
            return i
        } else {
            result = args.hasOwnProperty(i) ? args[i] : null
            if (result === null || result === undefined) {
                return ""
            }

            return result
        }

这里先检测是否是{{0}}这样的情况,如果是直接返回{0}
如果不是的话就进入替换流程,在args里面找,这里使用的是hasOwnProperty,如果没有就返回空字符串。

到此整个程序解剖完毕。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,273评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,874评论 18 399
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,281评论 0 4
  • 最基础的建立Android Library工程就不记录了 登陆Jcenter网站建立仓库 注意:不要建立企业账号(...
    生活理当如此阅读 592评论 0 1
  • 今天发工资啦啦啦啦,人生第一份工资,为啥没啥感觉,尴尬
    我又没蓝了阅读 157评论 0 0