/* ------------------------------
// 字符串模板1,语法严格,不能混用,效率相对较高
// 使用 {{ }} 作为标记是为了允许在模板中使用 JSON 字符串

// 用法 1(对象参数,对象可多次调用):
var say = "对 象:{{hi}}, {{to}}! {{hello}}, {{world}}!"
say = say.format({hi:"Hello", to:"World"})
         .format({hello:"你好", world:"世界"})
console.log(say)

// 用法 2(数组参数):
var say = "数 组:{{0}}, {{1}}! {{0}}!"
say = say.format(["Hello", "World"])
console.log(say)

// 用法 3(字符串参数,最后一个字符串可以重复使用):
var say = "字符串:{{.}}, {{.}}! {{.}}!"
say = say.format("Hello", "World")
console.log(say)

// 用法 4(多次调用,字符串和数组不能共用,字符串必须首先处理):

// 无数组
var say = "{{.}}:3 2 1, {{hi}}, {{to}}! {{hello}}, {{world}}!"
say = say.format("多 次")
         .format({hi: "Hello"})
         .format({to: "World"})
         .format({hello: "你好", world: "世界"})
console.log(say)

// 无字符串
var say = "多 次:{{2}} {{1}} {{0}}, {{hi}}, {{to}}! {{hello}}, {{world}}!"
say = say.format({hi: "Hello"})
         .format({to: "World"})
         .format([1,2,3])
         .format({hello: "你好", world: "世界"})
console.log(say)

// 字符串和数组共用
var say = "{{.}}:{{2}} {{1}} {{0}}, {{hi}}, {{to}}! {{hello}}, {{world}}!"
say = say.format("出问题")
         .format({hi: "Hello"})
         .format({to: "World"})
         .format([1,2,3])
         .format({hello: "你好", world: "世界"})
console.log(say)

// 没有首先处理字符串
var say = "出问题:{{.}}, {{hi}}, {{to}}! {{hello}}, {{world}}!"
say = say.format({hi: "Hello"})
         .format("3 2 1")
         .format({to: "World"})
         .format({hello: "你好", world: "世界"})
console.log(say)
------------------------------ */
String.prototype.format = function(arg) {
	// 安全检查(长度不能小于 {{.}},为后面下标引用做准备)
	var len = this.length
	if (len < 5) { return this }

	var start = 0, result = "", argi = 0

	for (var i=0; i<=len; i++) {
		// 处理 {{ }} 之外的内容
		if (this[i] === "{" && this[i-1] === "{") {
			result += this.slice(start, i-1)
			start = i-1
		} else if (this[i] === "}" && this[i-1] === "}") {
			// 获取 {{ }} 中的索引
			var index = this.slice(start+2, i-1)
			if (index === ".") {          // 字符串
				result += arguments[argi]
				// 最后一个字符串会重复使用
				if (argi < (arguments.length - 1)) {
					argi++
				}
				start = i+1
			} else {                      // 对象或数组
				if (arg[index] != null) {
					result += arg[index]
					start = i+1
				}
			}
		}
	}
	// 处理最后一个 {{ }} 之后的内容
	result += this.slice(start)

	return result
}

/* ------------------------------
// 字符串模板2,语法自由,使用灵活,效率相对较低(基本上模板1就够用了)
// 使用 {{ }} 作为标记是为了允许在模板中使用 JSON 字符串

// 用法 1(对象参数,对象可多次提供):
var say = "对 象:{{hi}}, {{to}}! {{hello}}, {{world}}!"
say = say.template({hi:"Hello", to:"World"}, {hello:"你好"}, {world:"世界"})
console.log(say)

// 用法 2(数组参数):
var say = "数 组:{{0}}, {{1}}! {{0}}!"
say = say.template(["Hello", "World"]);
console.log(say)

// 用法 3(字符串参数,最后一个字符串可以重复使用):
var say = "字符串:{{.}}, {{.}}! {{.}}!"
say = say.template("Hello", "World");
console.log(say)

// 用法 4(混用,对象、数组、字符串可以在参数的任意位置,对象可多次提供):
var say = "{{.}}:{{2}} {{1}} {{0}}, {{hi}}, {{to}}! {{.}}, {{.}}!"
say = say.template([1,2,3], "混 用", {hi: "Hello", to: "World"}, "你好", "世界");
console.log(say)

// 用法 5(多次调用,字符串参数要一次处理完,对象可多次提供):
var say = "{{.}}:{{2}} {{1}} {{0}}, {{hi}}, {{to}}! {{.}}, {{.}}!"
say = say.template([1,2,3])
         .template({hi: "Hello"})
         .template("多 次", "你好", "世界")
         .template({to: "World"});
console.log(say)
------------------------------ */
String.prototype.template = function() {
	// 安全检查(长度不能小于 {{.}},为后面下标引用做准备)
	var len = this.length
	if (len < 5) { return this }

	var start = 0, result = ""
	var objs = [], strs = [], stri = 0

	// 参数分类
	for (var i in arguments) {
		switch (typeof arguments[i]) {
			case "object": objs.push(arguments[i]);break // 对象(包括数组,可以有多个)
			default      : strs.push(arguments[i])       // 其它(当做字符串处理)
		}
	}

	for (var i=0; i<len; i++) {
		// 处理 {{ }} 之外的内容
		if (this[i] === "{" && this[i-1] === "{") {
			result += this.slice(start, i-1)
			start = i-1
		} else if (this[i] === "}" && this[i-1] === "}") {
			// 获取 {{ }} 中的索引
			var index = this.slice(start+2, i-1)
			if (index === "." && strs.length > 0) { // 字符串
				result += strs[stri]
				// 最后一个字符串会重复使用
				if (stri < strs.length - 1) {
					stri++
				}
				start = i+1
			} else {                                // 对象或数组
				for (var obji in objs) {
					if (objs[obji][index] != null) {
						result += objs[obji][index]
						start = i+1
						continue
					}
				}
			}
		}
	}
	// 处理最后一个 {{ }} 之后的内容
	result += this.slice(start)

	return result
}

代码片段 - JavaScript 字符串模板的更多相关文章

  1. JavaScript——字符串——模板字符串

    JavaScript--字符串--模板字符串 字符串可以用反引号包裹起来,其中的${expression}表示特殊的含义,JavaScript会将expression代表的变量的值和反引号中的其它普通 ...

  2. vs _ 用户代码片段 _ html模板

    自定义模板:首选项 -> 用户代码片段 - >(如果没有自己创个)html.json t : 表示缩进 n:表示换行 ----------------------------------- ...

  3. 项目中解决实际问题的代码片段-javascript方法,Vue方法(长期更新)

    总结项目用到的一些处理方法,用来解决数据处理的一些实际问题,所有方法都可以放在一个公共工具方法里面,实现不限ES5,ES6还有些Vue处理的方法. 都是项目中来的,有代码跟图片展示,长期更新. 1.获 ...

  4. HTML代码转换为JavaScript字符串

    我有时在工作中用到字符串拼接基本上来自于此,链接 http://www.css88.com/tool/html2js/

  5. [欣赏代码片段] (JavaScript) 你使用过getComputedStyle没有

    (function() { // IE8 ployfill for GetComputed Style (for Responsive Script below) if (!window.getCom ...

  6. [欣赏代码片段] (JavaScript) Responsive jQuery

    jQuery(document).ready(function($) { /* getting viewport width*/ var responsive_viewport = $(window) ...

  7. vscode 用户代码片段 vue初始化模板 Snippet #新加入开头注释 自动生成文件名 开发日期时间等内容

    vue文件模板 模板变量 https://code.visualstudio.com/docs/editor/userdefinedsnippets#_variables vue.json { // ...

  8. [代码片段]javascript检查图片大小和格式

    function checkImgType(input) { var this_ = document.getElementsByName('imgFile')[0]; var filepath = ...

  9. 代码片段 - JavaScript 求时间差

    // 求时间差1(时间差不能超过一天) function timeDifference1(startTime, endTime) { let times = endTime.getTime() - s ...

随机推荐

  1. 分布式文件系统--GFS

    分布式文件系统 分布式文件系统:当数据集的大小超过一台独立物理计算机的存储能力时,就有必要对它进行分区(partition)并存储到若干台单独的计算机上.管理网络中夸多台计算机存储的文件系统.这种系统 ...

  2. 学生成绩管理系统 1.0(Java+MySql)

    真难…… 数据库建立不会,中文编码不会,插入数据不会,删除不会…… Java读入数据不会……数据库连接不会…… 你也好意思说自己是学计算机的啊魂淡…… 我会慢慢写2.0,3.0版的……噗…… src/ ...

  3. Django 1.6 最佳实践: 如何正确使用 Signal(转)

    原文:http://www.weiguda.com/blog/38/ 如何正确的使用signal: 简单回答是: 在其他方法无法使用的情况下, 才最后考虑使用signal. 因为新的django开发人 ...

  4. socket编写简单回显server

    socket在公司代码中应用比较广,比如接口调用的IPCRPC机制,经常看到这样的代码,但是一直也没有动手写过. 在某个比较大的进程中创建一个子进程,由于父子进程复制会浪费内存,可以将创建进程的命令通 ...

  5. Java安装程序制作

    对于Java桌面应用来说,比较烦琐的就是安装部署问题,如:客户端是否安装有jre.jre版本.jre在哪里下载.如何用jre启动 Java应用等等.不要说刚接触电脑的人,就算是比较熟悉电脑,如果没有接 ...

  6. C#中的Collection 3

    IList<T> 和 ICollection<T> 最重要的一些类型 List<T>: Encapsulates[T], like array, but also ...

  7. webstorm 主题设置 皮肤设置

    推荐个编辑器主题下载的一个网站. Color Themes    网址:http://color-themes.com [点这里直接跳转] 但是,只支持几个编辑器. 各种颜色搭配的主题,随你选择!我个 ...

  8. TMS3705A PCF7991AT 线路图

  9. ubuntu12.04_64bit adb shell

    1.#adb shell 提示error: insufficient permissions for device 解决办法: 1)sudo gedit /etc/udev/rules.d/51-an ...

  10. 搭建Spring + SpringMVC + Mybatis框架之二(整合Spring和Mybatis)

    整合Spring和Mybatis 首先给出完整的项目目录: (1)引入项目需要的jar包 使用http://maven.apache.org作为中央仓库即可. Spring核心包,mybatis核心包 ...