UDN-企业互联网技术人气社区

板块导航

浏览  : 511
回复  : 2

[原生js] JavaScript 中 with 的替代语法和String 的正则方法

[复制链接]
htmlman的头像 楼主
发表于 2017-1-2 15:36:45 | 显示全部楼层 |阅读模式
  这几天在升级自己的MVVM 框架,遇到很多小问题,就在这里统一解决了.

  with 语法

  在代码中,要执行这么一个函数
  1. function computeExpression(exp, scope) {
  2.     try {
  3.         with (scope) {
  4.             return eval(exp);
  5.         }
  6.     } catch (e) {
  7.         console.error('ERROR', e);
  8.     }
  9. }
复制代码

  要求在scope 作用域中执行,什么意思???

  比如
  1. scope = {a:10,b:5};
  2. exp = a*b;
复制代码

  要求计算结果为15,这种情况,常规情况下要使用 with语法。

  但是:

  js的解释器需要检查with块中的变量是否属于with包含的对象,这将使with语句执行速度大大下降,并且导致js语句很难被优化。

  在严格模式中,with语法是被禁用的。

  而我使用ES6语法来编写这个库的,默认启用了严格模式了。所以不得已,自己模拟了一个with 的语法。

  先看代码
  1. function replaceWith(scopeName, exp) {
  2.     exp = " " + exp.trim();
  3.     let quickRegex = /([\s\+\-\*\/%&\|\^!\*~]\s*?)([a-zA-Z_$][a-zA-Z_$0-9]*?)/g;
  4.     exp = exp.replace(quickRegex, (a, b, c) => {
  5.         return b + scopeName + '.' + c;
  6.     });
  7.     return exp;
  8. }
复制代码

  首先把首位的空格全部去掉,为了和后面的统一,在开头加上一个空格。

  第一个正则匹配出犹如 "t.e==0 ? f : d" 的表达式中的 变量 会被作为 c 提取出来,符号作为 b 提取出来。

  测试一下
1.png

  现在已经可以返回一个表达式了,改装一下,让表达式直接在里面执行
  1. function replaceWith(scope, exp) {
  2.     exp = " " + exp.trim();
  3.     let quickRegex = /([\s\+\-\*\/%&\|\^!\*~]\s*?)([a-zA-Z_$][a-zA-Z_$0-9]*?)/g;
  4.     exp = exp.replace(quickRegex, (a, b, c) => {
  5.         return b + 'scope.' + c;
  6.     });
  7.     let func = new Function("scope", "return " + exp);
  8.     return func(scope);
  9. }
复制代码

  测试一下
2.png

  大功告成。

  可能中间正则写的不好,还有其他不严密的地方,欢迎园友补充。

  String 原型上的正则方法

  好久都没怎么写过大量代码了,看到 Sring.prototype.split(//); 这个正则表达式,竟然把分割符号都给加到数组中了,很惊讶,在MDN上学了一下。顺便做个整理,算是补充吧。
  1. String.prototype.split(separator,[limit])
复制代码

  separator:指定用来分割字符串的字符(串)。separator 可以是一个字符串或正则表达式。 如果忽略 separator,则返回整个字符串的数组形式。如果 separator 是一个空字符串,则 str 将会把原字符串中每个字符的数组形式返回。

  limit一个整数,限定返回的分割片段数量。split 方法仍然分割每一个匹配的 separator,但是返回的数组只会截取最多 limit 个元素。

  当找到一个 seperator 时,separator 会从字符串中被移除,返回存进一个数组当中的子字符串。如果忽略 separator 参数,则返回的数组包含一个元素,该元素是原字符串。如果 separator 是一个空字符串,则 str 将被转换为由字符串中字符组成的一个数组。

  注意:

  Note: 当字符串为空时,split 返回一个包含一个空字符串的数组,而不是一个空数组。

  如果 separator 是一个正则表达式,且包含捕获括号(capturing parentheses),则每次匹配到 separator 时,捕获括号匹配的结果将会插入到返回的数组中。
  1. var myString = "hello world";
  2. var splits = myString.split(();

  3. console.log(splits);
复制代码

  输出
  1. ["hello world"]

  2. var myString = "Hello 1 word. Sentence number 2.";
  3. var splits = myString.split(/(\d)/);

  4. console.log(splits);
复制代码

  输出
  1. Hello ,1, word. Sentence number ,2,.
复制代码

  String.prototype.replace()

  这个方法开始已经用到,就不再介绍。

  String.prototype.match(Regex)

  当字符串匹配到正则表达式(regular expression)时,match() 方法会提取匹配项。

  如果正则表达式没有 g 标志,返回和 RegExp.exec(str) 相同的结果。而且返回的数组拥有一个额外的 input 属性,该属性包含原始字符串。另外,还拥有一个 index 属性,该属性表示匹配结果在原字符串中的索引(以0开始)。
  1. "1aef2af3ef4 5".match(/[a-z]*(\d)/)
复制代码

  输出
  1. ["1", "1"]
复制代码

  如果正则表达式包含 g 标志,则该方法返回一个包含所有匹配结果的数组。如果没有匹配到,则返回 null。

  注意,如果加g, 则分组无用
  1. "1aef2af3ef4 5".match(/[a-z]*(\d)/g)
复制代码

  输出
  1. ["1", "aef2", "af3", "ef4", "5"]

  2. String.prototype.search(Regex)
复制代码

  search() 方法执行一个查找,看该字符串对象与一个正则表达式是否匹配。

  如果匹配成功,则 search() 返回正则表达式在字符串中首次匹配项的索引。否则,返回 -1。

  类似于正则表达式的 test 方法 。
  1. "aeg56".search(/[a-z]\d+/)
复制代码

  输出
  1. 2
复制代码

相关帖子

发表于 2017-1-2 15:37:15 | 显示全部楼层
LZ是闲人,天天发帖,坚定完毕
使用道具 举报

回复

发表于 2017-1-4 12:35:11 | 显示全部楼层
前排支持下
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部