我发现自己经常在JavaScript中解析所谓的名称值列表中的值。
我使用了一个自制的函数,它做得很好,但是我决定用prototype属性进行实验。它似乎是有效的,但是我发现第二个函数"nvlSet“有点”丑陋“。
你觉得是吗?..如果是这样,你认为它如何才能变成一种更“优雅”的方式来完成这项工作。
if(!String.prototype.nvlGet) {
String.prototype.nvlGet = function(nme,def){
return((rem0=new RegExp('(\\b|,)' + nme + '=([^\\b][^,]*)').exec(this)) ? rem0[2] : def);
}
}
if(!String.prototype.nvlSet) {
String.prototype.nvlSet = function(nme,val){
var re0=new RegExp('(\\b' + nme + '=[^\\b][^,]*)');
if(re0.test(this)) return(this.replace(re0,nme + "=" + val));
re0.compile('(,' + nme + '=[^\\b][^,]*)');
return(this.replace(re0,',' + nme + "=" + val));
}
}
var lst='firstName=John,lastName=Smith,department=Sales';
alert(lst.nvlGet('firstName')); // John
alert(lst.nvlGet('surName','none')); // none
lst=lst.nvlSet('department','Research');
alert(lst.nvlGet('department','unknown')); // Research
alert(lst); // firstName=John,lastName=Smith,department=Research另外,我想避免像这里这样的“双重赋值”:
lst=lst.nvlSet('department','Research');类似这样的东西:
lst.nvlSet('department','Research');然而,我找不到一个方法来做这件事。
发布于 2012-10-11 07:43:51
我建议的是将nvls序列化和反序列化成对象。一个相当简单的例子是:
function deserialize(nvl) {
var re = /(\w+)=(\w+)/g, matches, props = {};
while (matches = re.exec(nvl)) {
props[matches[1]] = matches[2];
}
return props;
}
function serialize(props) {
var prop, nvl = [];
for (prop in props) {
if (props.hasOwnProperty(prop)) {
nvl.push(prop + '=' + props[prop]);
}
}
return nvl.join(',');
}现在你的例子变成了:
var props = deserialize('firstName=John,lastName=Smith,department=Sales');
alert(props.firstName); // John
alert(props.surName); // undefined
props.department = 'Research';
alert(props.department); // Research
alert(serialize(props)); // firstName=John,lastName=Smith,department=Research发布于 2012-10-11 07:59:02
字符串在javascript中是不可变的。您永远不能更改当前字符串对象的内容。这就是为什么所有对字符串进行操作的string方法都会返回一个新的string对象。因此,您想要的结构是:
lst.nvlSet('department','Research');您希望它修改当前字符串对象的位置不能执行。
您可以创建自己的常规对象来保存状态,然后拥有获取或设置该状态的方法,如下所示:
function nvl(str) {
this.data = {};
if (str) {
this.data = this.parse(str);
}
}
nvl.prototype = {
parse: function(str) {
var result = {}, pieces;
var items = str.split(",");
for (var i = 0; i < items.length; i++) {
pieces = items[i].split("=");
result[pieces[0]] = pieces[1];
}
return(result);
},
get: function(key, defaultVal) {
var val = this.data[key];
if (val === undefined) {
val = defaultVal;
}
return(val);
},
set: function(key, value) {
this.data[key] = value;
},
serialize: function() {
var arr = [];
for (var i in this.data) {
if (this.data.hasOwnProperty(i)) {
arr.push(i + "=" + this.data[i]);
}
}
return(arr.join(","));
}
};工作示例:http://jsfiddle.net/jfriend00/3urJF/
发布于 2012-10-11 12:33:40
这样如何:
//add nvl as a method to String prototype
String.prototype.nvl = function(){
//new prototype for the dictionary object that gets returned
var proto = {
//convert the object literal back into a nvl
toNvl: function(){
var str = [];
for(var i in this){
if( this.hasOwnProperty(i) ){
str.push(i+'='+this[i]);
}
}
//return str.join(',');
return str.join(',');
}
},
//set the prototype of the object literal to our own
dict = Object.create(proto);
//convert the string into an object literal
keys = this.split(',');
keys.forEach(function(val, index, arr){
arr = val.split('=');
dict[arr[0]] = arr[1];
});
return dict;
}
var pop = 'color=blue,num=234'.nvl(); //convert the string to an object
pop.color = 'red'; //access object properties normally.
pop = pop.toNvl(); //convert back to nvl. reassignment is unfortunately necessaryhttps://stackoverflow.com/questions/12829909
复制相似问题