打字.如何获取对象'的属性名称与其值不同
Typescript. How to get object's property name from its value?
我正在编写一个用于不可变映射的typescript类
class NavigableObject<T> {
constructor(private obj: T, private path: string[] = []) { }
To<R>(p: (x: T) => R): NavigableObject<R> {
return new NavigableObject<R>(p(this.obj),
this.path.concat(this.getPropName(p(this.obj))));
}
getPath() {
return this.path;
}
private getPropName(value) {
for (var item in this.obj) {
if (this.obj[item] === value) {
return item;
}
}
}
}
let test = {
a: {
a1: 1,
a2: 1
},
b: {
b1: 1,
b2: 2
}
}
let navigableTest = new NavigableObject(test);
navigableTest.To(m => m.b).To(m => m.b2).getPath(); // = ["b", "b2"]
navigableTest.To(m => m.a).To(m => m.a2).getPath(); // = ["a", "a1"] <-- I selected a2, tho
getPropName
方法存在问题。当obj
有两个具有相同值的属性时,将只匹配第一个属性。
有人知道如何解决这个问题吗
您可以使用以下方式获取属性名称:
class NavigableObject<T> {
constructor(private obj: T, private path: string[] = []) { }
To<R>(p: (x: T) => R): NavigableObject<R> {
return new NavigableObject<R>(p(this.obj),
this.path.concat(this.getPropName(p)));
}
getPath() {
return this.path;
}
private static propertyRegEx = /'.([^'.;]+);?'s*'}$/;
private getPropName(propertyFunction: Function) {
return NavigableObject.propertyRegEx.exec(propertyFunction.toString())[1];
}
}
let test = {
a: {
a1: 1,
a2: 1
},
b: {
b1: 1,
b2: 2
}
}
let navigableTest = new NavigableObject(test);
navigableTest.To(m => m.b).To(m => m.b2).getPath(); // = ["b", "b2"]
navigableTest.To(m => m.a).To(m => m.a2).getPath(); // = ["a", "a2"]
未来就在这里。根据Tim Perry的链接,TypeScript现在添加了keyof
,这是获取类的可用属性的一个很好的功能。
用法,根据TypeScript文档:
interface Person {
name: string;
age: number;
location: string;
}
type K1 = keyof Person; // "name" | "age" | "location"
type K2 = keyof Person[]; // "length" | "push" | "pop" | "concat" | ...
type K3 = keyof { [x: string]: Person }; // string
使用当前的查询方法没有什么简单的事情可以做。你选择的属性不明确,所以没有简单的方法可以找到正确的路径。这并不是说你的代码现在是"错误的",只是有两个可能的正确答案,而且是任意选择的一个。
你可以改变它选择哪一个可能的键的规则,但没有合理的规则可以可靠地为你提供正确的答案。或者,你可以返回所有可能的答案,并有一个模糊的路径,但这似乎并不是你想要的。
可能有一种选择,可以做一些疯狂的事情,比如解析Esprima提供的函数,甚至正则表达式,以确定哪些属性被抓取,但这通常是个坏主意。这可能是复杂而脆弱的,不可靠的,除非您能够保证To()
中提供的代码的确切形状,并且运行速度也很慢。
如果你确实想选择这样的属性并知道特定的路径,你必须给To
函数提供属性的键,而不仅仅是一个函数来获得它所包含的值。这是一个不那么优雅的API,但它是唯一明智的方式,你将得到你正在寻找的行为:
class NavigableObject<T> {
constructor(private obj: T, private path: string[] = []) { }
To<R>(p: string): NavigableObject<R> {
return new NavigableObject<R>(this.obj[p],
this.path.concat(p));
}
getPath() {
return this.path;
}
}
let test = {
a: {
a1: 1,
a2: 1
},
b: {
b1: 1,
b2: 2
}
}
let navigableTest = new NavigableObject(test);
navigableTest.To('b').To('b2').getPath();
navigableTest.To('a').To('a2').getPath();
将来可能会在TypeScript中使用类型安全性来实现这一点,但现在不行。这份PR正在调查这些问题,但仍在讨论中,因此需要一段时间才能实施。请注意,它仍然从上面的例子中提出了基于字符串的方法,只是类型系统将检查字符串常量是否是所用类型的有效属性名。
不要在找到的第一个值上终止for,而是返回一个具有匹配值的名称数组。我把如何处理多个名字的问题留给你。
private getPropName (value) {
var items = [];
for (var item in this.obj) {
if (this.obj[item] === value)
items.push (item);
return items;
}
- RegEx删除空属性?例如,如果(class=“”||class=“”)移除;否则就下课
- 全局变量和全局对象的属性之间有什么区别吗
- 如果使用 lodash 将属性存在于另一个对象中,则向对象添加属性
- 如何在Bootstrap Modal中为动态点击生成的变量设置jade属性
- 序列化数据属性中对象的最可靠方法
- 分析高度属性时出现意外值{{specs.height}}.index.html
- TypeError:无法读取属性'推'未定义的JavaScript
- 同样,同样的错误'ahorcado.js:26未捕获类型错误:无法读取属性'beginPath'
- AngularJS-使用'true'属性
- 可以't使用JavaScript获取width属性
- 未捕获的TypeError无法读取未定义的属性socialsharing
- 如何使用javascript获取嵌套对象中所有子对象的单个属性
- JavaScript Pub/Sub属性访问问题
- 从JavaScript访问struts操作中的属性
- 是否可以从父类访问子类的属性
- 在restangular中获取名为post的属性
- 是否有人获得了在IE10中工作的javascript msProtocols属性
- 如何获得数组或属性值的键
- 获取用javascript编写的href属性
- 在 JavaScript 中使用重排隐藏元素,它与 CSS 隐藏属性有何不同