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,如果没有就返回空字符串。

到此整个程序解剖完毕。

你可能感兴趣的:(string-template解析(梁王的代码解剖室))