增强String replace方法,实现对字符串进行模板替换,支持对象、数组

原创
2017/10/23 15:48
阅读数 1.2K

        在拼接字符串时,我以前基本用+来进行拼接;当遇到很长的字符串,且需要拼接的点很多时,代码就很复杂容易搞错,而且很不美观。于是我想到了能不能像angular和vue处理html元素一样用{{param}}进行绑定,就像下面的代码:

var OUT_IMAGE_VIEW = 'http://localhost:8088/image/exitStation.jpg',
    EXIT_STATIONAME = '长沙西';
'<a class="fancybox" href="{{OUT_IMAGE_VIEW}}" title="出口收费站:{{EXIT_STATIONAME}}">'

        OUT_IMAGE_VIEW和EXIT_STATIONAME为变量,通过我的方法这些变量将自动拼接到字符串里面。输出的结果字符串为:

'<a class="fancybox" href="http://localhost:8088/image/exitStation.jpg" title="出口收费站:长沙西">'

        到这里,我心里在想,像这种方法肯定有很多前辈写出来了,或者某种框架插件里面能实现这种字符串的处理。不管那么多,我先百度一把,于是找到了它:http://www.jb51.net/article/79311.htm。一看完全符合我的胃口,接下来我就做我最拿手的活了:copy代码

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, variable = variables[i]; i < length; ++i) {
      currentObject = currentObject[variable];
      if (currentObject === undefined || currentObject === null) return '';
    }
 
    return currentObject;
  })
}

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.

        结果发现,然并卵,输出来的是:

        问题不大,就是author.name没有解析,整体思路和逻辑肯定没问题。到这里我就只能单步调试看看能不能找出它的问题咯,看着他的文章开始我的研究。经过我一顿操作,发现问题出在for循环时,i取值的问题,variable = variables[i]没有随循环运行,所以一直取得variables[0]的值。修改后的代码:

String.prototype.render = function(context) {

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

    return this.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;

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

        return currentObject;
    });
};

        测试结果:

        成功,可是,又遇到了问题,这个方法只支持对象,不支持数组,而我的数据源是对象数组,我要实现的效果像这样:

var stringFmt = {
  out: {
    OUT_IMAGE_VIEW: 'http://localhost:8088/image/exitStation.jpg',
    EXIT_STATIONAME: '长沙西'
  }
  point: [{
    POINT_IMAGE_VIEW: 'http://localhost:8088/image/pointStation1.jpg',
    POINT_STATIONAME: '益阳'
  }, {
    POINT_IMAGE_VIEW: 'http://localhost:8088/image/pointStation2.jpg',
    POINT_STATIONAME: '衡阳'
  }]
}

'<a class="fancybox" href="{out.OUT_IMAGE_VIEW}" title="出口收费站:{out.EXIT_STATIONAME}">'
'<a class="fancybox" href="{point[0].POINT_IMAGE_VIEW}" title="识别收费站1:{point[0].POINT_STATIONAME}">'
'<a class="fancybox" href="{point[1].POINT_IMAGE_VIEW}" title="识别收费站2:{point[1].POINT_STATIONAME}">'

        又开始我的研究,最终代码如下:

// 字符串模板匹配
String.prototype.render = function(context) {

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

    return this.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;

        for (i = 0, length = variables.length; i < length; ++i) {
            var curVariables = variables[i].split('['); // 用`[`进行字符串分割 a[0][1] → ["a", "0]", "1]"]
            currentObject = currentObject[curVariables[0]]; // 第一位是数组名
            if (curVariables.length > 1) { // 如果大于1,则有`[`符号,就是数组对象
                curVariables.shift();  // 去掉数组名,循环["0]", "1]"]
                curVariables.forEach(function(item) {
                    currentObject = currentObject[parseInt(item.substr(0, 1))]; // 用数组的索引取值
                });
            }
            if (currentObject === undefined || currentObject === null) return '';
        }

        return currentObject;
    });
};

        第一次写博客,感觉有点啰嗦,哈哈,不知道这样实现合不合理,至少我实现了我想要的,继续加油!!

展开阅读全文
加载中

作者的其它热门文章

打赏
0
11 收藏
分享
打赏
2 评论
11 收藏
0
分享
返回顶部
顶部