从 ES6 javascript 中的字符串动态创建方法(非浏览器)
Dynamically create a method from a string in ES6 javascript (non browser)
在 javascript 代码中,我有一个字符串定义对象内的 属性 路径。例如
var def = "contact.email"
如何从这个字符串中得到以下函数?
o => o.contact.email
这样我就可以按以下方式使用它了:
var person = {
name: 'Test',
contact: { email: 'test@test.test' }
}
var emailGetter = MagicCompileFunction('contact.email');
var email = emailGetter(person);
// here, email should hold the value of person.contact.email
路径字符串在编译时未知。也可以由用户提供。
该解决方案也应该适用于非浏览器环境(没有 window
对象),例如在 NodeJS 服务器端 javascript.
我知道一个解决方案是创建一个通用方法,将一个对象和一个字符串作为参数(例如 valueGetter(person, "contact.email")
),其中字符串定义对象内的路径,然后拆分每个点 '.' 上的字符串并遵循对象上的路径。但我不希望在每次调用 getter
函数时都执行此算法。我需要一个动态编译的方法,它会给我一个最终的 getter,它会立即访问所需的 (sub)属性。
我喜欢这个问题,所以我想出了一个解决方案。这应该按照您的要求进行,无需使用 eval...
function MagicCompileFunction(mapping) {
mapping = mapping.split(".");
return (function(obj) {
var result = obj;
for (var idx in mapping) {
result = result[mapping[idx]];
}
return result;
});
}
var person = {
name: "Test",
contact: {
email: "test@test.test"
}
}
var emailGetter = MagicCompileFunction("contact.email");
var email = emailGetter(person);
var nameGetter = MagicCompileFunction("name");
var name = nameGetter(person);
console.log(email);
console.log(name);
MagicCompileFunction()
return 是一个函数,它使用您在创建 getter 对象时使用的映射来启动。然后,您可以将任何人传递到该对象以 return 相关数据。
您可以使用 Function constructor
实现此目的
var person = {
name: 'Test',
contact: { email: 'test@test.test' }
}
var maginFunction = (def) => new Function('o','return o.'+ def);
var emailGetter = maginFunction('contact.email');
var email = emailGetter(person);
console.log(email);
您可以简单地动态访问嵌套对象属性,如下所示;
function dynPropAcc(o,s){
return s.split(".")
.reduce((p,q,i) => i-1 ? p[q] : o[p][q]);
}
var def = "contact.email.2",
obj = {contact: {name: "John", email: { 1: "john@x.com", 2: "john@y.com"}}};
console.log(dynPropAcc(obj,def));
ES6 比 稍微多一点:
function MagicCompileFunction(mapping) {
return (obj => mapping.split(".").reduce((curr, name) => curr[name], obj));
}
var person = {
name: "Test",
contact: {
email: "test@test.test"
}
}
var emailGetter = MagicCompileFunction("contact.email");
var email = emailGetter(person);
var nameGetter = MagicCompileFunction("name");
var name = nameGetter(person);
console.log(email);
console.log(name);
在 javascript 代码中,我有一个字符串定义对象内的 属性 路径。例如
var def = "contact.email"
如何从这个字符串中得到以下函数?
o => o.contact.email
这样我就可以按以下方式使用它了:
var person = {
name: 'Test',
contact: { email: 'test@test.test' }
}
var emailGetter = MagicCompileFunction('contact.email');
var email = emailGetter(person);
// here, email should hold the value of person.contact.email
路径字符串在编译时未知。也可以由用户提供。
该解决方案也应该适用于非浏览器环境(没有 window
对象),例如在 NodeJS 服务器端 javascript.
我知道一个解决方案是创建一个通用方法,将一个对象和一个字符串作为参数(例如 valueGetter(person, "contact.email")
),其中字符串定义对象内的路径,然后拆分每个点 '.' 上的字符串并遵循对象上的路径。但我不希望在每次调用 getter
函数时都执行此算法。我需要一个动态编译的方法,它会给我一个最终的 getter,它会立即访问所需的 (sub)属性。
我喜欢这个问题,所以我想出了一个解决方案。这应该按照您的要求进行,无需使用 eval...
function MagicCompileFunction(mapping) {
mapping = mapping.split(".");
return (function(obj) {
var result = obj;
for (var idx in mapping) {
result = result[mapping[idx]];
}
return result;
});
}
var person = {
name: "Test",
contact: {
email: "test@test.test"
}
}
var emailGetter = MagicCompileFunction("contact.email");
var email = emailGetter(person);
var nameGetter = MagicCompileFunction("name");
var name = nameGetter(person);
console.log(email);
console.log(name);
MagicCompileFunction()
return 是一个函数,它使用您在创建 getter 对象时使用的映射来启动。然后,您可以将任何人传递到该对象以 return 相关数据。
您可以使用 Function constructor
实现此目的var person = {
name: 'Test',
contact: { email: 'test@test.test' }
}
var maginFunction = (def) => new Function('o','return o.'+ def);
var emailGetter = maginFunction('contact.email');
var email = emailGetter(person);
console.log(email);
您可以简单地动态访问嵌套对象属性,如下所示;
function dynPropAcc(o,s){
return s.split(".")
.reduce((p,q,i) => i-1 ? p[q] : o[p][q]);
}
var def = "contact.email.2",
obj = {contact: {name: "John", email: { 1: "john@x.com", 2: "john@y.com"}}};
console.log(dynPropAcc(obj,def));
ES6 比
function MagicCompileFunction(mapping) {
return (obj => mapping.split(".").reduce((curr, name) => curr[name], obj));
}
var person = {
name: "Test",
contact: {
email: "test@test.test"
}
}
var emailGetter = MagicCompileFunction("contact.email");
var email = emailGetter(person);
var nameGetter = MagicCompileFunction("name");
var name = nameGetter(person);
console.log(email);
console.log(name);