解决wxs不能通过for…in遍历对象的问题

本文介绍了如何在微信小程序中使用wxs编写一个遍历对象的polyfill,以解决wxs不支持for…in的限制,提供了详细的代码实现和使用示例。

wxs是微信小程序中特有的一种脚本语言,配合wxml可辅助实现各种视图层的业务逻辑。其作用主要在wxml中进行一些简单的数据处理并输出到绑定变量的页面中,也可以说能将wxs当做vue中的computed使用。但是wxs并不是支持for…in的语法,在有遍历对象的需求中会带来一些不便~ 以往的解决方案是配合js使用或者直接绕开不能遍历对象的坑,为了从根本上解决此问题,本人写了一个基于wxs遍历对象的polyfill,希望能够帮助到有需要的童鞋们~

  • polyfill的具体实现如下: 
function forEachObj(obj, callback) {
  var json = JSON.stringify(obj)
    .replace(getRegExp('\n', 'g'), '')
    .replace(getRegExp('^\{'), '')
    .replace(getRegExp('\}$'), '')
    .trim();
  if (typeof callback !== 'function' || json === '') return;
  var specialExp = getRegExp('\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})', 'g');
  var contExp = getRegExp('"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?', 'g');
  var dangerousExp = getRegExp('[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]', 'g');
  dangerousExp.lastIndex = 0;
  var commaExp = getRegExp('\,', 'g');
  var bklExp = getRegExp('\[', 'g');
  var bkrExp = getRegExp('\]', 'g');
  var bslExp = getRegExp('\{', 'g');
  var bsrExp = getRegExp('\}', 'g');
  if (dangerousExp.test(json)) {
    json = json.replace(dangerousExp, function(str) {
      return '\\u' + ('0000' + str.charCodeAt(0).toString(16)).slice(-4);
    });
  }
  var specialFlags = json.match(specialExp) || [];
  var dedupFlags = [];
  for (var sp = 0; sp < specialFlags.length; sp++) {
    var item = specialFlags[sp];
    if (dedupFlags.indexOf(item) === -1) {
      dedupFlags.push(item);
    }
  }
  dedupFlags.sort(function(a,b) {
    var perv = a.split('').filter(function(f) { return '\\' === f }).length;
    var next = b.split('').filter(function(f) { return '\\' === f }).length;
    return next - perv;
  });
  // 特殊字符转义(随机字符串为防止JSON内容中有与转义字符串内容冲突的可能)
  // , comma value
  // [ bkl value
  // ] bkr value
  // { bsl value
  // } bsr value
  // 随机转义符生成
  var rmSize = 7;
  var ltSize = rmSize + dedupFlags.length;
  var letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
  var randomList = [];
  for (var l = 0; l < ltSize; l++) {
    var flag = true;
    while(flag) {
      var strList = [];
      while(strList.length < 5) {
        var idx = Math.floor(Math.random() * letters.length);
        if (strList.indexOf(letters[idx]) === -1) {
          strList.push(letters[idx]);
        }
      }
      var joinStr = '@' + strList.join('') + '@';
      if (randomList.indexOf(joinStr) === -1 && json.indexOf(joinStr) === -1) {
        randomList.push(joinStr);
        flag = false;
      }
    }
  }
  var replaceMap = {
    comma: randomList[0],
    bkl: randomList[1],
    bkr: randomList[2],
    bsl: randomList[3],
    bsr: randomList[4],
    contSplit: randomList[5],
    split: randomList[6]
  };
  var specialRandoms = randomList.slice(rmSize, ltSize);
  // 特殊字符转义
  var eqFlag = '\\'.charAt(0);
  for (var dpf = 0; dpf < dedupFlags.length; dpf++) {
    var item = dedupFlags[dpf];
    var targetItem = item.split('').map(function(m) {
      var isSpecFlag = m.charAt(0) === eqFlag;
      if (isSpecFlag) {
        m = eqFlag + m;
      }
      return m;
    }).join('');
    json = json.replace(getRegExp(targetItem, 'g'), specialRandoms[dpf]);
  }
  // 括号逗号字符转义
  var jsonConts = json.match(contExp) || [];
  var jsonFlags = json.replace(contExp, replaceMap.contSplit).split(replaceMap.contSplit);
  var joinJson = '';
  for (var j = 0; j < jsonConts.length; j++) {
    var item = jsonConts[j];
    if (commaExp.test(item) || bklExp.test(item) || bkrExp.test(item) || bslExp.test(item) || bsrExp.test(item)) {
      item = item
        .replace(getRegExp('\,$'), '')
        .replace(commaExp, replaceMap.comma)
        .replace(bklExp, replaceMap.bkl)
        .replace(bkrExp, replaceMap.bkr)
        .replace(bslExp, replaceMap.bsl)
        .replace(bsrExp, replaceMap.bsr);
    }
    joinJson += (jsonFlags[0] || '') + item;
    jsonFlags.shift();
  }
  json = joinJson + (jsonFlags[0] || '');
  // 以逗号分隔截取字符串
  var jsonList = json.replace(getRegExp('\,', 'g'), ',' + replaceMap.split).split(replaceMap.split);
  var count = 0;
  var jsonStr = '';
  for (var i = 0; i < jsonList.length; i++) {
    var item = jsonList[i];
    if (getRegExp('\[|\{|\]|\}').test(item)) {
      var start = item.match(getRegExp('\[|\{', 'g')) || [];
      var end = item.match(getRegExp('\]|\}', 'g')) || [];
      var diff = start.length - end.length;
      count += diff;
      jsonStr += item;
    } else if (count > 0) {
      jsonStr += item;
    } else if (count === 0 && jsonStr === '') {
      jsonStr = item;
    }
    if (count === 0) {
      // 完整的json在转义回来
      jsonStr = jsonStr
        .replace(getRegExp(replaceMap.comma, 'g'), ',')
        .replace(getRegExp(replaceMap.bkl, 'g'), '[')
        .replace(getRegExp(replaceMap.bkr, 'g'), ']')
        .replace(getRegExp(replaceMap.bsl, 'g'), '{')
        .replace(getRegExp(replaceMap.bsr, 'g'), '}');
      var keyStr = (jsonStr.match(getRegExp('"[^"\\\n\r]*"')) || [])[0] || '';
      var valueStr = jsonStr.replace(keyStr, '').replace(getRegExp('^:'),'').replace(getRegExp('\,$'), '') || '';
      for (var sr = 0; sr < specialRandoms.length; sr++) {
        var item = specialRandoms[sr];
        keyStr = keyStr.replace(getRegExp(item, 'g'), dedupFlags[sr]);
        valueStr = valueStr.replace(getRegExp(item, 'g'), dedupFlags[sr]);
      }
      var kv = JSON.parse('['+keyStr+','+valueStr+']');
      callback(kv[0], kv[1]);
      jsonStr = '';
    }
  }
}
  •  polyfill可以单独放到一个wxs文件(.wxs)中引用,使用方法如下:
// wxs文件中导出
module.exports.forEachObj = forEachObj;

//导入并使用
var feo = require('forEachObj.wxs');

var obj = {
  // ...something object
}

feo.forEachObj(obj, function(key, value) {
  // ...something code
});
  •  相关链接:

github源码链接:https://github.com/chenwei1012/for-each-object/tree/release-v1.0.0

gitee源码链接:https://gitee.com/chenwei1012/for-each-object/tree/master

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值