`
frank1998819
  • 浏览: 758036 次
  • 性别: Icon_minigender_1
  • 来自: 南京
文章分类
社区版块
存档分类

17 行代码实现的简易 Javascript 字符串模板(转)

    博客分类:
  • JS
 
阅读更多

原作者:http://www.thinksaas.cn/group/topic/399775/

 

这是源于两年前,当我在做人生中第一个真正意义上的网站时遇到的一个问题

该网站采用前后端分离的方式,由后端的 REST 接口返回 JSON 数据,再由前端渲染到页面上。

同许多初学 Javascript 的菜鸟一样,起初,我也是采用拼接字符串的形式,将 JSON 数据嵌入 HTML 中。开始时代码量较少,暂时还可以接受。但当页面结构复杂起来后,其弱点开始变得无法忍受起来:

  • 书写不连贯。每写一个变量就要断一下,插入一个+"。十分容易出错。

  • 无法重用。HTML 片段都是离散化的数据,难以对其中重复的部分进行提取。

  • 无法很好地利用<template>标签。这是 HTML5 中新增的一个标签,标准极力推荐将 HTML 模板放入 <template>标签中,使代码更简洁。

当时我的心情就是这样的:

为了解决这个问题,我暂时放下了手上的项目,花了半个小时实现一个极简易的字符串模板。

需求描述

实现一个render(template, context)方法,将template中的占位符用context填充。要求:

  1. 不需要有控制流成分(如 循环、条件 等等),只要有变量替换功能即可

  2. 级联的变量也可以展开

  3. 被转义的的分隔符{}不应该被渲染,分隔符与变量之间允许有空白字符

例子:

render('My name is {name}', {
 name: 'hsfzxjy'
}); // My name is hsfzxjy

render('I am in {profile.location}', {
 name: 'hsfzxjy',
 profile: {
 location: 'Guangzhou'
}
}); // I am in Guangzhou

render('{ greeting }. \{ This block will not be rendered }', {
 greeting: 'Hi'
}); // Hi. { This block will not be rendered }

实现

先写下函数的框架:

function render(template, context) {

}

显然,要做的第一件事便是匹配模板中的占位符

匹配占位符

匹配的事,肯定是交给正则表达式来完成。那么,这个正则表达式应该长什么样呢?

根据 需求 1、2 的描述,我们可以写出:

var reg = /{([^{}]+)}/g;

至于需求 3,我第一个想到的概念是 前向匹配,可惜 Javascript 并不支持,只好用一个折衷的办法:

var reg = /(\)?{([^{}\]+)(\)?}/g;
// 若是第一个或第三个分组值不为空,则不渲染

现在,代码应该是这样:

function render(template, context) {

 var tokenReg = /(\)?{([^{}\]+)(\)?}/g;

 return template.replace(tokenReg, function (word, slash1, token, slash2) {
 if (slash1 || slash2) { // 匹配到转义字符
 return word.replace('\', ''); // 如果 分隔符被转义,则不渲染
}

 // ...
})
}

占位符替换

嗯,正则表达式确定了,接下来要做的便是替换工作。

根据 需求2,模板引擎不仅要能渲染一级变量,更要渲染多级变量。这该怎么做呢?

其实很简单:将token.分隔开,逐级查找即可:

var variables = token.replace(/s/g, '').split('.'); // 切割 token
var currentObject = context;
var i, length, variable;

// 逐级查找 context
for (i = 0, length = variables.length, variable = variables[i]; i < length; ++i)
 currentObject = currentObject[variable];

return currentObject;

不过,有可能token指定的变量并不存在,这时上面的代码便会报错。为了更好的体验,代码最好有一定的容错能力:

var variables = token.replace(/s/g, '').split('.'); // 切割 token
var currentObject = context;
var i, length, variable;

for (i = 0, length = variables.length; i < length; ++i) {
 variable = variables[i];
 currentObject = currentObject[variable];
 if (currentObject === undefined || currentObject === null) return ''; // 如果当前索引的对象不存在,则直接返回空字符串。
}

return currentObject;

把所有的代码组合在一起,便得到了最终的版本:

function render(template, context) {

 var tokenReg = /(\)?{([^{}\]+)(\)?}/g;

 return template.replace(tokenReg, function (word, slash1, token, slash2) {
 if (slash1 || slash2) { 
 return word.replace('\', '');
}

 var variables = token.replace(/s/g, '').split('.');
 var currentObject = context;
 var i, length, variable;

 for (i = 0, length = variables.length; i < length; ++i) {
 variable = variables[i];
 currentObject = currentObject[variable];
 if (currentObject === undefined || currentObject === null) return '';
}
 return currentObject;
})
}

除去空白行,一共 17 行。

将函数挂到 String 的原型链

甚至,我们可以通过修改原型链,实现一些很酷的效果:

String.prototype.render = function (context) {
 return render(this, context);
};

之后,我们便可以这样调用啦:

"{greeting}! My name is { author.name }.".render({
 greeting:"Hi",
 author: {
 name:"hsfzxjy"
}
});
// Hi! My name is hsfzxjy.
分享到:
评论

相关推荐

    JSTE - 基于JavaScript语法的简易模板引擎

    1. **预编译**:将模板字符串转换为JavaScript函数,这个函数负责渲染模板。 2. **数据绑定**:将数据对象传递给预编译得到的函数,函数会根据数据填充模板。 3. **渲染**:执行函数,生成最终的HTML字符串。 **...

    【JavaScript源代码】Vue实现简易购物车案例.docx

    7. **过滤器(filters)**:Vue中的过滤器允许我们对数据进行格式化,如将数字价格转换为带有货币符号的字符串。`showPrice`过滤器用于格式化总价。 8. **数据(data)**:Vue实例的数据对象,`books`是一个包含...

    基于 ES6 的简易服务器端 WEB 模板引擎

    ES6,也称为 ECMAScript 2015,是 JavaScript 的一个重要更新,引入了许多新特性,如箭头函数、模板字符串、类和模块等。这些特性使得编写更简洁、可读性强的代码成为可能,同时也为创建服务器端模板引擎提供了便利...

    html+JavaScript实现的一个小型的商城

    我们可能还涉及到了一些JavaScript的高级特性,如闭包、异步操作(如Promise或async/await)、AJAX(Asynchronous JavaScript and XML)用于前后端数据交换,以及可能的ES6语法糖,如箭头函数、模板字符串等。...

    C#实现一个简易浏览器代码

    这里,`webBrowser1`是WebBrowser控件的实例名,`Navigate()`方法接收一个字符串参数,表示要访问的URL。 **5. 监听导航事件** 我们可以监听WebBrowser控件的导航事件,如`Navigating`和`DocumentCompleted`,以...

    JavaScrip简易教程.rar_javascrip_javascript

    10. **ES6及以后的新特性**:包括类(class)、模板字符串、解构赋值、let和const、箭头函数、Promise等,这些都是现代JavaScript开发的必备知识。 此外,"www.pudn.com.txt"可能是提供下载资源或额外信息的文本...

    LocalStorage+HTML+CSS+jQuery 实现简易的学生管理系统

    在ES6中,我们可以使用模板字符串、箭头函数、let和const变量声明、类和模块等新特性,使代码更简洁、易读。例如,可以创建一个JavaScript对象表示学生,用数组存储所有学生对象,然后使用数组方法(如push、pop、...

    HTML+CSS+JAVASCRIPT简易个人网站.zip

    此外,现代浏览器还支持ES6(ECMAScript 2015)等新特性,如箭头函数、模板字符串、类等,提供了更简洁、高效的编程语法。 在压缩包中的"简易个人网站"文件夹中,你可能会找到以下文件: 1. HTML文件(如index.html...

    用javasc制作简易计算器

    3. **数值处理**:JavaScript提供了处理数学运算的内置对象Math,以及字符串和数字的转换方法,如`parseInt`和`parseFloat`,这些都是计算过程中必不可少的部分。 4. **用户界面更新**:每次计算完成后,需要更新...

    使用Node.js实现简易MVC框架的方法

    **views** 为了简化,我们可以使用字符串模板来模拟视图。在 `views` 文件夹下创建 `templates` 子文件夹,然后创建 `list.html` 模板文件,用于展示演员列表。 **views/templates/list.html** ```html &lt;h1&gt;Actor ...

    mfc 简易网页解析器

    在这个环境中,我们可以使用MFC库,并通过其向导生成MFC应用程序模板,然后添加自定义代码来实现网页解析功能。 为了实现这个简易网页解析器,开发者可能首先会使用`CInternetSession`和`CHttpFile`类从网络上下载...

    Javascript 页面模板化很多人没有使用过的方法

    传统的方法中,页面模板化常常是通过字符串拼接的方式实现的。例如,使用JavaScript的`+=`操作符或数组的`push`方法来逐步构建HTML字符串,然后将其赋值给页面中的某个元素。这种方法虽简单,但在处理复杂的HTML结构...

    JS简易年历源码

    这涉及到JavaScript的字符串拼接或模板字符串的使用。 6. 函数封装与模块化:为了代码的可读性和可维护性,源码通常会将不同的功能封装成独立的函数,甚至采用模块化设计,如立即执行函数表达式(IIFE)或ES6的模块...

    基于H5 Canvas的在线简易word编辑器

    1. **ES6**:ECMAScript 2015(也称为ES6)是JavaScript语言的一个新版本,引入了许多现代编程特性,如类、模块、箭头函数、模板字符串等。在这个项目中,开发者可能利用了ES6的这些新特性来编写更简洁、可维护的...

    JsonCpp 简易封装 v2.2

    在实际使用中,开发者可以通过JsonCpp简易封装库提供的接口,轻松地将C++对象转换成JSON字符串进行网络传输,或者接收JSON数据并解码为C++对象进行本地处理。例如,一个简单的例子可能涉及读取JSON文件,解析成...

    JavaScript实现简易的天数计算器实例【附demo源码下载】

    在本文中,我们将深入探讨如何使用JavaScript实现一个简易的天数计算器。这个计算器的主要功能包括支持用户选择日期、自动计算闰年以及允许用户选择使用当前日期。以下是对这个实例的详细解析: 首先,HTML文件是...

    js手工调薪输入表达式代码.zip

    9. **代码优化**:为了提高代码的可读性和性能,可以使用ES6的语法特性,如箭头函数、模板字符串等,并遵循良好的编码规范。 10. **测试与调试**:编写完成后,务必进行详尽的测试,确保所有功能正常运行。使用...

    react-ReactReactrouterreduxlesses6实现的简易备忘录

    4. **ES6**:ECMAScript 6(也称为ES2015)是JavaScript语言的一个重要版本,引入了许多新特性,如类、箭头函数、模板字符串、解构赋值等。在这个项目中,开发者使用了ES6的语法糖来编写更简洁、可读性更强的代码,...

    IOS实现简易天气预报功能适合初学者

    在iOS开发中,实现简易天气预报功能是一项常见的需求,尤其对于初学者来说,这是一个很好的实践项目。本教程将介绍如何利用iOS技术栈,包括Objective-C(OC)编程语言、AFNetworking库以及JSON数据解析,来创建一个...

Global site tag (gtag.js) - Google Analytics