在 ReactNative 中,如何在不检查所有前面变量可用性的情况下检查嵌套变量的可用性?
How to check for availability for a nested variable without checking all the preceding variable availability, in ReactNative?
例如,在iOSSwift中,我可以这样做:
if (self.user?.company?.pic?.phoneNumber != null) { doSomething() }
不需要:
if (self.user != null && self.user!.company != null && self.user!.company!.pic != null && self.user!.company!.pic!.phoneNumber != null) { doSomething() }
在ReactNative(或Javascript)中,我发现如果一个对象是未定义的,我无法检查它里面的变量是否存在,所以我必须先检查对象是否是否未定义,只有这样我才能安全地检查它里面的变量是否未定义。
if (typeof this.state.user !== "undefined" && typeof this.state.user.company !== "undefined" && typeof this.state.user.company.pic !== "undefined" && typeof this.state.user.company.pic.phoneNumber !== undefined) { this.doSomething() }
我怎样才能把它变成:
if (typeof this.state.user.company.pic.phoneNumber !== "undefined") { this.doSomething() }
或类似的东西?
谢谢。
如果您不能使用 optional chaining which is still a proposal but available via babel plugin,您可以使用递归实用函数来测试每个路径段的存在:
const pluck = (item, path) => {
const [, part, rest] = /^([^.]+)\.*(.*)/.exec(path) || [];
if (!part) {
return null;
}
const o = (item || {})[part];
if (o == null) {
return null;
}
return rest.length ? pluck(o, rest) : o;
};
if (pluck(this.state, ‘user.company.pic.phoneNumber’)) {
doSomething();
}
目前,可选链接是 stage 3 draft,因此,您将来可能能够做到。
编辑:
Optional chaining 现在将成为 ES2020 的一部分,因此您将能够执行以下操作:
if (self.user?.company?.pic?.phoneNumber !== undefined) {
doSomething(); // phoneNumber exists
}
尽管如此,它的浏览器支持仍然非常有限。
因此,目前您可以改为创建一个函数,该函数从属性列表中递归查找每个对象,如下所示:
const optional_chain = (obj, [key, ...props]) =>
obj !== undefined && key ? optional_chain(obj[key], props) : obj;
const user = {
company: {
pic: {
phoneNumber: 1
}
}
}
console.log(optional_chain(user, ['company', 'pic', 'phoneNumber'])); // 1
console.log(optional_chain(user, ['company', 'pic', 'phoneNumber', 'x'])); // undefined
console.log(optional_chain(user, ['company', 'picture', 'phoneNumber'])); // undefined
console.log(optional_chain(user, ['x', 'picture', 'phoneNumber'])); // undefined
在您的情况下,用法如下:
if (optional_chain(self.user, ['company', 'pic', 'phoneNumber']) !== undefined) {
doSomething();
}
例如,在iOSSwift中,我可以这样做:
if (self.user?.company?.pic?.phoneNumber != null) { doSomething() }
不需要:
if (self.user != null && self.user!.company != null && self.user!.company!.pic != null && self.user!.company!.pic!.phoneNumber != null) { doSomething() }
在ReactNative(或Javascript)中,我发现如果一个对象是未定义的,我无法检查它里面的变量是否存在,所以我必须先检查对象是否是否未定义,只有这样我才能安全地检查它里面的变量是否未定义。
if (typeof this.state.user !== "undefined" && typeof this.state.user.company !== "undefined" && typeof this.state.user.company.pic !== "undefined" && typeof this.state.user.company.pic.phoneNumber !== undefined) { this.doSomething() }
我怎样才能把它变成:
if (typeof this.state.user.company.pic.phoneNumber !== "undefined") { this.doSomething() }
或类似的东西?
谢谢。
如果您不能使用 optional chaining which is still a proposal but available via babel plugin,您可以使用递归实用函数来测试每个路径段的存在:
const pluck = (item, path) => {
const [, part, rest] = /^([^.]+)\.*(.*)/.exec(path) || [];
if (!part) {
return null;
}
const o = (item || {})[part];
if (o == null) {
return null;
}
return rest.length ? pluck(o, rest) : o;
};
if (pluck(this.state, ‘user.company.pic.phoneNumber’)) {
doSomething();
}
目前,可选链接是 stage 3 draft,因此,您将来可能能够做到。
编辑: Optional chaining 现在将成为 ES2020 的一部分,因此您将能够执行以下操作:
if (self.user?.company?.pic?.phoneNumber !== undefined) {
doSomething(); // phoneNumber exists
}
尽管如此,它的浏览器支持仍然非常有限。
因此,目前您可以改为创建一个函数,该函数从属性列表中递归查找每个对象,如下所示:
const optional_chain = (obj, [key, ...props]) =>
obj !== undefined && key ? optional_chain(obj[key], props) : obj;
const user = {
company: {
pic: {
phoneNumber: 1
}
}
}
console.log(optional_chain(user, ['company', 'pic', 'phoneNumber'])); // 1
console.log(optional_chain(user, ['company', 'pic', 'phoneNumber', 'x'])); // undefined
console.log(optional_chain(user, ['company', 'picture', 'phoneNumber'])); // undefined
console.log(optional_chain(user, ['x', 'picture', 'phoneNumber'])); // undefined
在您的情况下,用法如下:
if (optional_chain(self.user, ['company', 'pic', 'phoneNumber']) !== undefined) {
doSomething();
}