如何检查变量是否包含某个属性?
假设:
var x = 'some string';
然后我想这样做:
if ('trim' in x)
但这给了我一个:
Uncaught TypeError: Cannot use 'in' operator to search for 'trim' in string
我可以通过使用以下方法使其工作:
'trim' in x.__proto__
但根据 __proto__
说法,它已被弃用,并且它的使用(引用)“存在争议且不鼓励”。
那么我该如何实现这个目标呢?
我曾尝试使用Object.keys(x)
,但它仅列出了作为索引有效的键,而不是属性。
我知道,在这个特定的例子中,我可以简单地使用typeof x === 'string'
,但这不是一个通用的解决方案。
10
最佳答案
4
如果由于某种原因您想要避免通过直接访问该属性x[prop]
,您可以先将值传递给Object
函数,然后再使用进行测试in
。
let x = 'some string';
console.log(x != null && 'trim' in Object(x));
4
-
为什么你要更改答案以包含对 null 的检查?如果
x = null
你原来的答案工作正常,不是吗?(返回 false)
– -
1@LukasKroess
"toString" in Object(null)
是true
– -
1@LukasKroess
Object(null)
或Object(undefined)
返回一个空对象,这样你就会得到'toString' in Object(null)
真实的结果。
– -
@VLAZ (+还有@Unmitigated) 我明白了。感谢你们两位的提醒。
–
|
该运算符不适用于原始值。还有一个与之相同的运算符in
,但也有相同的限制。
但是,解决这个问题的一个简单方法是通过传递值而不使用new
。这样做会将原语转换为其包装器类,而如果输入是对象,则会按原样返回。因此,Object("a string")
与 相同,new String("a string")
但Object({ some: "object" })
与 相同{ some: "object" }
。这将允许通过in
(或Reflect.has()
)查找这些值。
需要注意的是,Object(null)
或Object(undefined)
将创建一个普通对象。这可能会对类似的东西返回假阳性"toString in Object(null)
。由于这两个值不能具有属性,因此可以使用以下方法将它们排除在检查之外:
target != null && prop in Object(target)
演示:
const prop = "trim";
function propIn(target, prop) {
return target != null && prop in Object(target);
}
const string = "a string";
const number = 42;
const bigint = 42n;
const boolean = true;
const symbol = Symbol("a symbol");
const obj = {an: "object"};
const objWithProp = {trim() { return "object with a .trim() method"; } }
console.log( propIn(string , prop));
console.log( propIn(number , prop));
console.log( propIn(bigint , prop));
console.log( propIn(boolean , prop));
console.log( propIn(symbol , prop));
console.log( propIn(null , prop));
console.log( propIn(undefined , prop));
console.log( propIn(obj , prop));
console.log( propIn(objWithProp, prop));
.as-console-wrapper { max-height: 100% !important; }
1
-
1谢谢。这似乎确实是完整的答案。我只是觉得将@Unmitigated 的答案标记为已接受是公平的,因为他们几分钟前发布了完全相同的方法。
–
|
hasProperty
您可以验证任何变量是否具有类似以下代码片段中的函数的属性。
function hasProperty ( mySubject, myProperty )
{
if ( ! ((mySubject === null) || (mySubject === undefined)) )
{
if ( (typeof mySubject == 'function') || (typeof mySubject == 'object') )
{
return Reflect.has(mySubject, myProperty);
}
else if ( typeof mySubject[myProperty] != 'undefined' )
{
// Note that here mySubject is a primitive value.
// Properties can not be defined in primitives, but
// can be defined on primitive prototypes.
return true;
}
}
return false;
}
// TESTING //
const mySubject1 = 'Anything goes here';
const mySubject2 = 300;
const mySubject3 = new Object;
const mySubject4 = undefined;
const mySubject5 = { valueOf: undefined };
const mySubject6 = Object.create(null);
mySubject6.valueOf = Object.prototype.valueOf;
console.log('mySubject1 =', mySubject1);
console.log('mySubject2 =', mySubject2);
console.log('mySubject3 =', mySubject3);
console.log('mySubject4 =', mySubject4);
console.log('mySubject5 =', mySubject5);
console.log('mySubject6 =', mySubject6);
console.log('Is mySubject1.valueOf defined?', hasProperty(mySubject1, 'valueOf'));
// Outputs: Is mySubject1.valueOf defined? true
console.log('Is mySubject2.valueOf defined?', hasProperty(mySubject2, 'valueOf'));
// Outputs: Is mySubject2.valueOf defined? true
console.log('Is mySubject3.valueOf defined?', hasProperty(mySubject3, 'valueOf'));
// Outputs: Is mySubject3.valueOf defined? true
console.log('Is mySubject4.valueOf defined?', hasProperty(mySubject4, 'valueOf'));
// Outputs: Is mySubject3.valueOf defined? false
console.log('Is mySubject5.valueOf defined?', hasProperty(mySubject5, 'valueOf'));
// Outputs: Is mySubject5.valueOf defined? true
console.log('Is mySubject6.valueOf defined?', hasProperty(mySubject6, 'valueOf'));
// Outputs: Is mySubject6.valueOf defined? true
注意,你可以使用Reflect.has(obj, prop)
。但是如果obj
没有通过obj instanceof Object
,则会引发异常,这就是使用mySubject1
、mySubject2
或mySubject4
作为obj
参数时发生的情况。
7
-
请解释如何解决这个问题。仅提供代码的答案不是好答案
– -
1@DarkBee 我觉得这个可能是。我还问“我该如何检查”,他回答说“你可以这样检查”,然后提供了代码。你还希望他写什么?
– -
1“你可以这样检查”不是一个答案。答案不只是针对 OP,还针对未来遇到类似问题的读者。
–
-
typeof mySubject[myProperty] != 'undefined'
不会告诉您是否缺少某个属性。它可能存在,但其值可能是undefined
:考虑obj = { hello: undefined }
然后hasProperty(obj, "hello")
两者hasProperty(obj, "world")
都返回false
,但只有其中一个属性缺失。
– -
@VLAZ 谢谢。我编辑了脚本,现在它已经完成了。现在无论如何它都可以工作了。
–
|
要检查变量是否包含某个属性或方法,可以将 typeof 运算符与 Object.getPrototypeOf() 结合使用,以安全地访问原型,而无需使用proto。具体操作如下:
var x = 'some string';
function hasMethod(obj, method) {
return typeof Object.getPrototypeOf(obj)[method] === 'function';
}
if (hasMethod(x, 'trim')) {
console.log("The string has the 'trim' method.");
} else {
console.log("The string does not have the 'trim' method.");
}
Object.getPrototypeOf(obj):这将获取对象的原型,而无需使用已弃用的proto。
typeof … === ‘function’:检查指定的方法是否存在并且确实是一个函数。
这种方法用途广泛,可用于检查任何对象的方法,而不仅仅是字符串。只需将对象和方法名称作为字符串传递给 hasMethod 函数即可。
1
-
1
hasMethod({trim() { return "has a trim method" } }, "trim")
将会回归false
–
|
–
'trim' in Object.getPrototypeOf(x)
返回true
。–
x.trim
–
in
。x.someProp
并不一定意味着它缺失,例如{ someProp: undefined }
–
–
|