Comments (17)
function anonymous(vm0) {
'use strict';
var test2 = vm0.test2, test1 = vm0.test1
return test1 && test2
}
function anonymous(vm0) {
'use strict';
var test1 = vm0.test1, test2 = vm0.test2
return test2 && test1
}
function anonymous(vm0) {
'use strict';
var test1 = vm0.test1, test2 = vm0.test2
return test2 || test1
}
这是新parser生成的求值函数
function anonymous(test1372575919386) {
with(test1372575919386){
var ret1372575919386 = test1 && test2
}
return ret1372575919386
}
function anonymous(test1372575919387) {
with(test1372575919387){
var ret1372575919387 = test2 && test1
}
return ret1372575919387
}
function anonymous(test1372575919389) {
with(test1372575919389){
var ret1372575919389 = test2 || test1
}
return ret1372575919389
}
这是旧parser生成的求值函数
from avalon.
var rule = item.rule;
var names = rule.replace(/["|']\w*["|']/g, ' ').match(/\w+/g); // 先replace掉字符串,匹配到的变量名赋给names
/*去掉重复的项和JS关键字*/
var unique = {};
names = dojo.filter(names, function(name) {
if (!unique[name]) {
unique[name] = true;
return dojo.indexOf(smartdot.Validator.keyword, name) === -1;
} else {
return false;
}
});
var param = [];
var arg = [];
dojo.forEach(names, function(name) {
if (name in smartdot.Validator.cache.index) {
param.push(smartdot.Validator.cache.get(name).get('value'));
arg.push(name);
}
});
return item.lambda('(' + arg.join(', ') + ') => (' + item.rule + ')').apply(item, param);
跟我之前做的一个小功能思路一样
from avalon.
这里可以帮你省下几个字符。
按你的需求来说,是要提取类似全局变量的变量名,除了eval之类的使用字符串生产变量的东西。
所以,在遇到那些关键字,直接用try、catch来走一边并缓存成相应的hash表,就可以了,并不会影响性能,毕竟缓存了。
贴上地址:https://gist.github.com/Gaubee/5938254
因为有用到循环,所以顺便把你getValueFunction里面那个filter写在一起。
from avalon.
另外细看你的正则,有坑:单双引号的字符串匹配竟然就这样写:'[^']*'|"[^"]*"
遇到"nihao"dajiahao"就出问题了。
比如
"nihao\"dajiahao" ; test1&&test2;"nihao\"dajiahao"
中间那部分就直接被过滤掉了……
DoubleQuotedString = new RegExp('"(?:\\.|(\\\\\\")|[^\\""\\n])*"','g');//双引号字符串
SingleQuotedString = new RegExp("'(?:\\.|(\\\\\\')|[^\\''\\n])*'",'g');//单引号字符串
from avalon.
abcd 搞出的抽取变量的函数,我做了部分调整
var rword = /[^, ]+/g
function oneObject(array, val) {
if (typeof array === "string") {
array = array.match(rword) || []
}
var result = {},
value = val !== void 0 ? val : 1
for (var i = 0, n = array.length; i < n; i++) {
result[array[i]] = value
}
return result
}
function getVars(s) {
var s_kws = " break case catch continue default delete do else finally for function if in instanceof new return switch this throw try typeof var void while with null true false"
+ " abstract boolean byte char class const debugger double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile ";
var keywords = oneObject(s_kws)
var re_ws = /\s+/;
var re_comm = /\/\/[^\r\n\u2028\u2029]*|\/\*(?:\/|\**[^*/])*\*+\//;
var re_id = /[a-zA-Z_$][\w$]*/;
var re_punc = /~|\}|\|\||\|=|\||\{|\^=|\^|\]|\[|\?|>>>=|>>>|>>=|>>|>=|>|===|==|=|<=|<<=|<<|<|;|:|\.|-=|--|-|,|\+=|\+\+|\+|\*=|\*|\)|\(|&=|&&|&|%=|%|!==|!=|!|\/=?/;
var re_num = /0x[\dA-Fa-f]+|(?:(?:0|[1-9]\d*)(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?/;
var re_str = /"(?:[^"\\]|\\[\s\S])*"|'(?:[^'\\]|\\[\s\S])*'/;
var re = function(a) {
for (var i = 0; i < a.length; ++i)
a[i] = '(' + a[i].source + ')';
return RegExp(a.join('|') + '|', 'g');
}([re_ws, re_comm, re_id, re_punc, re_num, re_str]);
var beforeIsDot = false;
var r = [];
var t;
function f(all, ws, comm, id, punc, num, str) {
if (beforeIsDot) {
beforeIsDot = false;
}
else {
if (all == '.') {
beforeIsDot = true;
}
else {
if (id && !keywords[id])
r.push(id);
}
}
}
while (t = re.exec(s)) {
if (!t[0]) {
if (t.index != s.length)
throw Error("error: " + t.index);
break;
}
f.apply(null, t);
}
return r;
}
console.log(getVars("new Date()"))
from avalon.
@RubyLouvre 这种写法说实话,很不稳定,而且可读性又低,你让getVars解析一下getVars自己。
自己做一下测试就知道,我用之前从你那边修改的Gist(这个还是用上eval的低效)和这个新的做比较,对getVariables这个函数体进行解析,不论从 速度 、 可读性、 稳定性 上都比你后来贴上来的这段代码好多了。
附上测试地址:https://gist.github.com/Gaubee/5945554
from avalon.
那个注释正则,可以简化一下
var re_comm = ///[^\r\n\u2028\u2029]|/_[\s\S]?_//;
这样也更快一点
其中的 \u2028\u2029 也可以去掉
因为一般代码中不会出现这种字符
from avalon.
@RubyLouvre 你可以运行一下你自己自己写的那段代码,相比abcd写的,特别是遇上简单结构的,速度优势更加明显,因为代码结构上的优势。
你也可以运行一下我上面贴给你的测试代码。
总之我觉得还是用你之前自己写的那段比较好。abcd这代码明显是用在更复杂的分析,而你的代码只是用于变量的提取。
from avalon.
我现在不想用with了
比如说我的绑定属性里面有个items
而这个绑定属性在select元素上
如果用with, 它就找到元素的select属性,而不是VM的items属性,这真吐血
from avalon.
我早期想到的怪招,利用TypeError进行抽取
//将绑定属性的值或插值表达式里面部分转换一个函数compileFn,里面或包含ViewModel的某些属性
//而它们分分种都是setter, getter,成为双向绑定链的一部分
var regEscape = /([-.*+?^${}()|[\]\/\\])/g;
function escapeRegExp(target) {
//将字符串安全格式化为正则表达式的源码
return target.replace(regEscape, "\\$1");
}
var isStrict = (function() {
return !this;
})();
function insertScopeNameBeforeVariableName(e, text, scopeList, names, args, random) {
var ok = false;
if (window.dispatchEvent) { //判定是否IE9-11或者为标准浏览器
ok = e instanceof ReferenceError;
} else {
ok = e instanceof TypeError;
}
//opera9.61
//message: Statement on line 810: Undefined variable: nickName
//opera12
//Undefined variable: nickName
//safari 5
//Can't find variable: nickName
//firefox3-20 chrome
//ReferenceError: nickName is not defined
//IE10
//“nickName”未定义
//IE6
//'eee' 未定义
if (ok) {
if (window.opera) {
var varName = e.message.split("Undefined variable: ")[1];
} else {
varName = e.message.replace("Can't find variable: ", "")
.replace("“", "").replace("'", "");
}
varName = (varName.match(/^[\w$]+/) || [""])[0]; //取得未定义的变量名
for (var i = 0, scope; scope = scopeList[i++]; ) {
if (scope.hasOwnProperty(varName)) {
var scopeName = scope.$id + random;
if (names.indexOf(scopeName) === -1) {
names.push(scopeName);
args.push(scope);
}
//这里实际还要做更严格的处理
var reg = new RegExp("(^|[^\\w\\u00c0-\\uFFFF_])(" + escapeRegExp(varName) + ")($|[^\\w\\u00c0-\\uFFFF_])", "g");
return text.replace(reg, function(a, b, c, d) {
return b + scopeName + "." + c + d; //添加作用域
});
}
}
}
}
var doubleQuotedString = /"([^\\"\n]|\\.)*"/g;
var singleQuotedString = /'([^\\'\n]|\\.)*'/g;
from avalon.
取自我早期的avalon https://github.com/RubyLouvre/mass-Framework/blob/1.4/avalon.js#L1166
from avalon.
@RubyLouvre 过滤算法有更新,1、完善数字判断,避免BUG 2、完善字符串正则:
欢迎共同完善
from avalon.
做广告?
from avalon.
@limodou 楼主采用了我写的parser,他不知道有在BUG,我修复后再告诉他--这何来广告一说?
from avalon.
报歉,不知道前因后果。
from avalon.
原来几大高手一起合作在弄, 太赞了
from avalon.
var str = "aaa.bbb.ccc+ddd"
var str = "aaa[bbb].ccc-888+ikk"
var str = "aaa[ bbb ].ccc-888+ikk"
var str = "aaa['bbb'].ccc||a888&&ikk(ddd.eee)"
var str = 'aaa["aaa"]+null'
//取得变量名或属性名
var KEYWORDS =
// 关键字
'break,case,catch,continue,debugger,default,delete,do,else,false'
+ ',finally,for,function,if,in,instanceof,new,null,return,switch,this'
+ ',throw,true,try,typeof,var,void,while,with'
// 保留字
+ ',abstract,boolean,byte,char,class,const,double,enum,export,extends'
+ ',final,float,goto,implements,import,int,interface,long,native'
+ ',package,private,protected,public,short,static,super,synchronized'
+ ',throws,transient,volatile'
// ECMA 5 - use strict
+ ',arguments,let,yield'
+ ',undefined';
function oneObject(array, val) {
if (typeof array === "string") {
array = array.match(/[^, ]+/g) || []
}
var result = {},
value = val !== void 0 ? val : 1
for (var i = 0, n = array.length; i < n; i++) {
result[array[i]] = value
}
return result
}
var keywordOne = oneObject(KEYWORDS)
var rvar = /\b[\$\_a-z][\w$]*(?:\.[$\w]+|\[[^\]]+\])*/ig
var rstringLiterals = /(['"])(\\\1|.)+?\1/g
var rregexp = /([^\/])(\/(?!\*|\/)(\\\/|.)+?\/[gim]{0,3})/g
var rcomment1 = /\/\/.*?\/?\*.+?(?=\n|\r|$)|\/\*[\s\S]*?\/\/[\s\S]*?\*\//g
var rcomment2 = /\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g
function getVars(str) {
//http://james.padolsey.com/javascript/javascript-comment-removal-revisted/
var uid = '_' + +new Date(),
primatives = [],
primIndex = 0;
str = str
/* 移除所有字符串*/
.replace(rstringLiterals, function(match) {
primatives[primIndex] = match;
return (uid + '') + primIndex++;
})
/* 移除所有正则 */
.replace(rregexp, function(match, $1, $2) {
primatives[primIndex] = $2;
return $1 + (uid + '') + primIndex++;
})
.replace(rcomment1, "")
.replace(rcomment2, "")
.replace(RegExp('\\/\\*[\\s\\S]+' + uid + '\\d+', 'g'), "")
var vars = []
str.replace(rvar, function(a) {
if (keywordOne[a])
return
vars.push(a.replace(RegExp(uid + '(\\d+)', 'g'), function(match, n) {
return primatives[n];
}))
})
console.log(vars)
}
getVars(str)
from avalon.
Related Issues (20)
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from avalon.