文档章节

最简单的基于js实现的模版引擎

乌龟壳
 乌龟壳
发布于 2016/12/06 00:54
字数 474
阅读 51
收藏 2
点赞 0
评论 0

继之前推出的70行代码实现的lua模版引擎后,又遇到了需要在js实现模版引擎的需求,遂实现之

首先是模版引擎的代码

var JTemplateEngine = function() {
	
	var encodeAsString = function(s) {
		return s.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').replace(/\r/g, '\\r').replace(/\n/g, '\\n');
	}

	var compile = function(code) {
		console.log(code);
		// 输出缓冲
		var outBuf;
		// 仿php的echo函数,需要什么函数自己照着这个模式加就是了,项目中实际会有很多辅助函数
		var echo = function(s) {
			outBuf.push(s);
		}
		var __compiled;
		eval('__compiled = function(params) { ' + code + ' }');
		return function(params) {
			outBuf = new Array();
			__compiled(params);
			return outBuf.join('');
		}
	}

	var _class = function() { }

        // 解析模版字符串并编译
	_class.prototype.compile = function(template) {
		var codes = new Array();
		var buffer = new Array();
		var state = 0;
		for (i = 0; i <= template.length; i++) {
			var c;
			if (i == template.length) {
				c = '\0';
			} else {
				c = template.charAt(i);
			}
			switch (state) {
			case 0: // normal
				if (c == '{') {
					state = 1;
				} else if (c == '\0') {
					codes.push("echo('" + encodeAsString(buffer.join('')) + "');");
				} else {
					buffer.push(c);
				}
				break;
			case 1: // perhapse inside
				if (c == '%') {
					codes.push("echo('" + encodeAsString(buffer.join('')) + "');");
					buffer = new Array();
					state = 2;
				} else if (c == '\0') {
					buffer.push('{');
					codes.push("echo('" + encodeAsString(buffer.join('')) + "');");
				} else {
					buffer.push('{');
					buffer.push(c);
					state = 0;
				}
				break;
			case 2: // inside
				if (c == '%') {
					state = 3;
				} else if (c == '\0') {
					codes.push(buffer.join(''));
				} else {
					buffer.push(c);
				}
				break;
			case 3: // perhapse outside
				if (c == '}') {
					codes.push(buffer.join(''));
					buffer = new Array();
					state = 0;
				} else if (c == '\0') {
					buffer.push('%');
					codes.push(buffer.join(''));
				} else {
					buffer.push('%');
					buffer.push(c);
					state = 2;
				}
				break;
			default:
				alert("bug");
			}
		}
		return compile(codes.join('\n'));
	}

	return _class;
}();

接下来就用一个html页面来说明如何使用

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>template test</title>
</head>
<body>
	<div id="container"></div>
</body>
<script id="tmpl" type="text/html">
	<style>
		.t99 th, .t99 td { width: 30px; height: 30px; text-align: center;}
	</style>
	<table class="t99">
		<tr>
			<th></th>
			{% for (var i = 1; i <= params.max; i++) { %}
				<th>{% echo (i) %}</th>
			{% } %}
		</tr>
		{% for (var i = 1; i <= params.max; i++) { %}		
		<tr>
			<th>{% echo (i) %}</th>
			{% for (var j = 1; j <= params.max; j++) { %}
				<td>{% echo (i * j) %}</td>
			{% } %}
		</tr>
		{% } %}
	</table>
</script>
<script src="template.js"></script>
<script>
	var jtmpl = new JTemplateEngine();
	var tmpl1 = jtmpl.compile(document.getElementById('tmpl').innerHTML);
	document.getElementById('container').innerHTML = tmpl1({max: 9});
</script>
</html>

运行结果

输入图片说明

至于性能如何?个人项目中测试,需要渲染的页面重复生成十万次,只需要1秒多。

© 著作权归作者所有

共有 人打赏支持
乌龟壳
粉丝 111
博文 22
码字总数 13409
作品 0
深圳
程序员
Lynx技术分析-JS引擎扩展设计

JS Binding 技术 Lynx(一个高效的跨平台框架) 的 JS Binding 技术最主要的目的是搭建一个高效的与 JS 引擎解耦的通信桥梁,同时具备 JS 引擎切换的能力。该技术经历了多次迭代,最终通过抽...

hxxft ⋅ 05/15 ⋅ 0

【JSConf EU 2018】JavaScript引擎: 精粹部分

JSConf EU 2018圆满结束, 谷歌V8的开发者Mathias Bynens以及Benedikt Meurer一起发表了《JavaScript Engines: The Good Parts™》演讲,本文将带领大家回顾一下演讲上所提到的重点。 演讲第一...

想成为工匠的码农 ⋅ 昨天 ⋅ 0

襁褓中的 deno(零):初次见面,多多关照

襁褓中的 deno(零):初次见面,多多关照 const name: string = "yingying";console.log(name); yingying } 编辑于 03:44 文章被以下专栏收录...

嘤嘤 ⋅ 06/04 ⋅ 0

JavaScript 如何打败众语言,成为 Node 的实现语言?

Node.js 是一种将 JS 放在服务器端实现的平台,而为什么要把js放到服务器端实现,JS 最初设计是在浏览器端解释执行,后来为什么搞Node.js 把他放在服务器端执行呢? 关于这个问题,近日有网友...

达尔文 ⋅ 04/21 ⋅ 0

中式高性能报表引擎 UReport 2.2.7 正式版发布

修复的BUG: 优化代码压缩配置,减小压缩后JS体积 针对条件判断中对象属性取值加了null值判断,防止出现空指针的异常出现 修复条码或二维码在选择表达式时设计器存在JS错误的BUG #280 修复在...

youseries ⋅ 04/17 ⋅ 0

[译] JavaScript 是如何工作的:CSS 和 JS 动画背后的原理 + 如何优化性能

原文地址:How JavaScript works: Under the hood of CSS and JS animations + how to optimize their performance 原文作者:Alexander Zlatkov 译文出自:掘金翻译计划 本文永久链接:git......

辣手摧花 ⋅ 05/15 ⋅ 0

arguments 对象的老历史

本文经作者 柯拓 授权转载。原文地址:http://www.cnblogs.com/ziyunfei/p/5890322.html 引题:为什么 JavaScript 中的 arguments 对象不是数组 http://www.zhihu.com/question/50803453 Jav...

_朴灵_ ⋅ 05/14 ⋅ 0

融合了 JavaScript 之力的 Nashorn 或被 JDK 11 弃用

还没有使用过 Nashorn ?如果感兴趣的话,建议尽快去尝试一下,因为 Jim Laskey 最近提交了一个新的 JEP 335 草案,准备弃用 Nashorn JavaScript 脚本引擎、API 以及该 jjs 工具。 从 JDK 6 ...

王练 ⋅ 06/08 ⋅ 0

JavaScript 编年小史

1995 由 Netscape 公司雇员Brendan Eich 花不到 10 天时间开发出来。之所以叫 JavaScript,因为 Netscape 想开发一款类 Java 的脚本语言来增强 Web 技术用于和微软竞争。 1996 Netscape 提交...

CPPAlien ⋅ 05/09 ⋅ 0

PHP学习路线图 最全PHP自学指南

对于广大零基础的PHP自学者,往往不知道如何系统的学习PHP,导致平白浪费了很多时间。本文将为大家带来最详细的php学习路线图,同时还会附上相应的权威教程,让广大PHP自学者少走许多弯路。 ...

W3Cschool小编 ⋅ 04/24 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

MySQL主从复制原理、半同步操作步骤及原理

1.1 企业Linux运维场景数据同步方案 1.1.1 文件级别的异机同步方案 1、scp/sftp/nc 命令可以实现远程数据同步。 2、搭建ftp/http/svn/nfs 服务器,然后在客户端上也可以把数据同步到服务器。...

xiaomin0322 ⋅ 4分钟前 ⋅ 0

Oracle10g 数据及文件迁移过程[原]

QL*Plus: Release 10.2.0.1.0 - Production on 星期三 5月 11 10:22:35 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. 连接到: Oracle Database 10g Enterprise Edition Re......

harrypotter ⋅ 10分钟前 ⋅ 0

nginx安装

1:安装工具包 wget、vim和gcc yum install -y wget yum install -y vim-enhanced yum install -y make cmake gcc gcc-c++ 2:下载nginx安装包 wget http://nginx.org/download/nginx-1......

壹丶贰 ⋅ 13分钟前 ⋅ 0

ideaVim安装及配置

1.安装插件 File-Settings-Plugins,Browse Repositories,输入ideavim,安装。 重启后,在Tools-Vim Emulator启用。 2.快捷键设置 ideaViim键与idea快捷键有冲突,可以在Settings-Other Se...

Funcy1122 ⋅ 17分钟前 ⋅ 0

MySQL中B+Tree索引原理

B+树索引是B+树在数据库中的一种实现,是最常见也是数据库中使用最为频繁的一种索引。B+树中的B代表平衡(balance),而不是二叉(binary),因为B+树是从最早的平衡二叉树演化而来的。在讲B...

浮躁的码农 ⋅ 31分钟前 ⋅ 0

两道面试题,带你解析Java类加载机制

在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题: class Grandpa{ static { System.out.println("爷爷在静态代码块"); }} cl...

1527 ⋅ 35分钟前 ⋅ 0

SpringCloud(Data Flow)

dataflow-server

赵-猛 ⋅ 46分钟前 ⋅ 0

深入理解Java虚拟机

这本书我读到第8章,之后就是在读不下去了。 读到后面是一种痛苦的体验,太多的东西是不全面的,大量的专有名词是没有解释的,读到最后很多东西仅仅是一个侧面,所以我觉得,这本书不适合初学...

颖伙虫 ⋅ 51分钟前 ⋅ 0

NanoPi NEO core/ Ubuntu16.04单网卡配置3个IP地址(2个静态,1个动态)

配置 root@NanoPi-NEO-Core:/etc/network# cat interfacesauto loiface lo inet loopbackallow-hotplug eth0iface eth0 inet static address 172.31.188.249 netmask 255.......

SamXIAO ⋅ 今天 ⋅ 0

三步为你的App集成LivePhoto功能

摘要:LivePhoto是iOS9新推出的一种拍照方式,类似于拍摄Gif图或录制视频片段生成图片。如果没有画面感,可以联想《哈利波特》霍格沃茨城堡的壁画,哈哈,很炫酷有木有,但坑爹的是只有iphone6S以...

壹峰 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部