Javascript 函数组合的意外行为
我正在编写一个小的实用函数,用于将字符串从一个分词方案转换为另一个分词方案。整个项目都在使用它,我知道它附带了Javascript 函数组合的意外行为,javascript,lodash,Javascript,Lodash,我正在编写一个小的实用函数,用于将字符串从一个分词方案转换为另一个分词方案。整个项目都在使用它,我知道它附带了.camelCase之类的东西,但我觉得不使用那些方案转换帮助程序更具可扩展性 其想法是,其他开发人员可以轻松地将自己的方案定义添加到我已有的方案定义中: const CASES = [ {name: 'lower_kebab', pattern: /^[a-z]+(_[a-z]+)*$/g, to_arr: w=> w.split('_'), to_
.camelCase
之类的东西,但我觉得不使用那些方案转换帮助程序更具可扩展性
其想法是,其他开发人员可以轻松地将自己的方案定义添加到我已有的方案定义中:
const CASES = [
{name: 'lower_kebab', pattern: /^[a-z]+(_[a-z]+)*$/g,
to_arr: w=> w.split('_'),
to_str: a=> a.map(w=>w.toLowerCase()).join('_')},
{name: 'UpperCamel', pattern: /^([A-Z][a-z]*)+$/g,
to_arr: w=> w.match(/[A-Z][a-z]*/g),
to_str: a=> a.map(_.capitalize).join('')},
//...
];
因此,每个大小写
都需要一个模式来确定字符串是否属于该模式,一个to_arr
来适当地分割字符串,一个to_str
来将一个单词数组连接到该模式的字符串中(名称
是可选的,但最好是描述性的)。我把这两个都包括在内,因为它是从lower_kebab
到UpperCamel
的转换过程中,我得到了一些意想不到的行为
我实现了如下实际转换函数:
$(文档).ready(()=>{
风险值案例=[
{名称:'下烤肉串',图案:/^[a-z]+([a-z]+)*$/g,
to_arr:w=>w.split(''uu'),
to_str:a=>a.map(w=>w.toLowerCase()).join(“”)
},
{name:'UpperCamel',模式:/^([A-Z][A-Z]*)+$/g,
to_arr:w=>w.match(/[A-Z][A-Z]*/g),
to_str:a=>a.map(u.capitalize).join(“”)
},
//...
];
函数转换为(目标方案示例){
返回uu.compose(
CASES.find(c=>c.pattern.test(target\u scheme\u example)).to\u str
,str=>CASES.find(c=>c.pattern.test(str)).to_arr(str));
}
$('go')。在('click',()=>$('result')。文本(
将_转换为($('#dst').val())($('#src').val())
));
});
尝试“上骆驼肉”到“下烤肉串”,反之亦然
转换
结果:
来自:
在同一全局正则表达式实例上多次调用的test()
将超过上一个匹配项
这就是为什么它只在第一次工作的原因:正则表达式对象(模式
)保持先前对其执行测试
方法所产生的状态
要避免这种行为,可以执行以下操作之一:
模式
正则表达式中删除g
修饰符,因为它们对于您尝试执行的匹配类型不是必需的,或者return _.compose(
CASES.find(c=>target_scheme_example.match(c.pattern)).to_str
, str=> CASES.find(c=>str.match(c.pattern)).to_arr(str) );
}
test()
将超过上一个匹配项
这就是为什么它只在第一次工作的原因:正则表达式对象(模式
)保持先前对其执行测试
方法所产生的状态
要避免这种行为,可以执行以下操作之一:
模式
正则表达式中删除g
修饰符,因为它们对于您尝试执行的匹配类型不是必需的,或者return _.compose(
CASES.find(c=>target_scheme_example.match(c.pattern)).to_str
, str=> CASES.find(c=>str.match(c.pattern)).to_arr(str) );
}
CASES.find(c=>c.pattern.test(target\u scheme\u example)).to\u str
不保留任何关于Javascript中对象的to\u str
方法的信息。但是,你的似乎并不需要这些信息。我假设编写(或者更确切地说,编写的结果)会这样做,也就是说,为了运行f(g(x))
我需要保留f
和g
。有没有一个好的方法可以达到这个效果?你是否希望.compose(f,g)
在g
之前应用f
?这看起来像是你所期待的。我可以看到它看起来像什么,但我想我有正确的构图顺序。要应用的第一个函数(compose
的最后一个参数)应该是f:String->Array
,它是到arr
的签名。第一个参数的情况类似,但是使用to_str
时,您正在字符串->数组部分中使用c=>c.pattern.test(str)
,这将要求str
已经匹配模式。也许你把str
和target\u scheme\u示例
搞混了。CASES.find(c=>c.pattern.test(target\u scheme\u示例))。to\u str
不保留Javascript中对象的to\u str
方法。但是,你的似乎并不需要这些信息。我假设编写(或者更确切地说,编写的结果)会这样做,也就是说,为了运行f(g(x))
我需要保留f
和g
。有没有一个好的方法可以达到这个效果?你是否希望.compose(f,g)
在g
之前应用f
?这看起来像是你所期待的。我可以看到它看起来像什么,但我想我有正确的构图顺序。要应用的第一个函数(compose
的最后一个参数)应该是f:String->Array
,它是到arr
的签名。第一个参数的情况类似,但是使用to_str
时,您正在字符串->数组部分中使用c=>c.pattern.test(str)
,这将要求str
已经匹配模式。也许你把str
和target\u scheme\u示例
搞混了。在实际应用中,我可能通过将CASES
设置为const
使自己产生了一种虚假的安全感。从每个案例的模式中移除全局标志就成功了!事实上,const
只禁止重新分配到所讨论的变量,而不是它的突变。我可能通过在实际的ap中将CASES
设置为const
使自己陷入了一种错误的安全感