如何在JavaScript中检查对象是否具有特定属性?
考虑以下代码:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
那是最好的做法吗?
如何在JavaScript中检查对象是否具有特定属性?
考虑以下代码:
x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}
那是最好的做法吗?
今天2020年12月17日,我在Chrome v87、Safari v13.1.2和Firefox v83上对所选解决方案进行了MacOs HighSierra 10.13.6的测试。
我仅比较A-F的解决方案,因为它们对详细部分中使用的所有情况都给出了有效的结果。所有浏览器都适用。
in
(A)的解决方案最快或者是最快的has
(B)的解决方案最慢我执行了4个测试案例:
下面的代码段介绍了解决方案之间的差异: A B C D E F G H I J K
// SO https://dev59.com/_HVC5IYBdhLWcg3w9GHM
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#14664748
function A(x) {
return 'key' in x
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#11315692
function B(x) {
return _.has(x, 'key')
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#40266120
function C(x) {
return Reflect.has( x, 'key')
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM
function D(x) {
return x.hasOwnProperty('key')
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#11315692
function E(x) {
return Object.prototype.hasOwnProperty.call(x, 'key')
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#136411
function F(x) {
function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}
return hasOwnProperty(x,'key')
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#135568
function G(x) {
return typeof(x.key) !== 'undefined'
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#22740939
function H(x) {
return x.key !== undefined
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#38332171
function I(x) {
return !!x.key
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#41184688
function J(x) {
return !!x['key']
}
// src: https://dev59.com/_HVC5IYBdhLWcg3w9GHM#54196605
function K(x) {
return Boolean(x.key)
}
// --------------------
// TEST
// --------------------
let x1 = {'key': 1};
let x2 = {'key': "1"};
let x3 = {'key': true};
let x4 = {'key': []};
let x5 = {'key': {}};
let x6 = {'key': ()=>{}};
let x7 = {'key': ''};
let x8 = {'key': 0};
let x9 = {'key': false};
let x10= {'key': undefined};
let x11= {'nokey': 1};
let b= x=> x ? 1:0;
console.log(' 1 2 3 4 5 6 7 8 9 10 11');
[A,B,C,D,E,F,G,H,I,J,K ].map(f=> {
console.log(
`${f.name} ${b(f(x1))} ${b(f(x2))} ${b(f(x3))} ${b(f(x4))} ${b(f(x5))} ${b(f(x6))} ${b(f(x7))} ${b(f(x8))} ${b(f(x9))} ${b(f(x10))} ${b(f(x11))} `
)})
console.log('\nLegend: Columns (cases)');
console.log('1. key = 1 ');
console.log('2. key = "1" ');
console.log('3. key = true ');
console.log('4. key = [] ');
console.log('5. key = {} ');
console.log('6. key = ()=>{} ');
console.log('7. key = "" ');
console.log('8. key = 0 ');
console.log('9. key = false ');
console.log('10. key = undefined ');
console.log('11. no-key ');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!
这里是Chrome的示例结果:
这里是另一种特定情况的选项。:)
如果你想测试一个对象上的成员,并且想知道它是否已经被设置为非以下内容:
那么你可以使用:
var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
// member is set, do something
}
根据具体用例,以下是一些更简单、更短的选项:
运行代码片段以查看结果:
let obj1 = {prop:undefined};
console.log(1,"prop" in obj1);
console.log(1,obj1?.prop);
let obj2 = undefined;
//console.log(2,"prop" in obj2); would throw because obj2 undefined
console.log(2,"prop" in (obj2 ?? {}))
console.log(2,obj2?.prop);
let obj3 = {prop:false};
console.log(3,"prop" in obj3);
console.log(3,!!obj3?.prop);
let obj4 = {prop:null};
let look = "prop"
console.log(4,"prop" in obj4);
console.log(4,obj4?.[look]);
let obj5 = {prop:true};
console.log(5,"prop" in obj5);
console.log(5,obj5?.prop === true);
let obj6 = {otherProp:true};
look = "otherProp"
console.log(6,"prop" in obj6);
console.log(6,obj6.look); //should have used bracket notation
let obj7 = {prop:""};
console.log(7,"prop" in obj7);
console.log(7,obj7?.prop || "empty");
我很少看到hasOwn
被正确使用,特别是考虑到它的继承问题
尽管有30个答案试图解释hasOwn和hasOwnProperty之间的区别,但我仍然很难理解它们之间的区别。这里是一个可运行的代码片段,你可以自己看看它的行为。
const object1 = {
prop: 'exists'
};
object1.property1 = 42;
// the following as you might expect output true
console.log(object1.hasOwnProperty('property1'));
console.log(Object.hasOwn(object1,"prop"));
console.log(Object.hasOwn(object1,"property1"));
// the following might surpize you, they output false
console.log(Object.hasOwnProperty(object1,"prop"));
console.log(Object.hasOwnProperty(object1,"property1"));
// the following as you rightfully expect output false
console.log(object1.hasOwnProperty('toString'));
console.log(Object.hasOwn(object1,"toString"));
console.log(Object.hasOwnProperty(object1,"toString"));
console.log(object1.hasOwnProperty('hasOwnProperty'));
console.log(Object.hasOwn(object1,"hasOwnProperty"));
console.log(Object.hasOwnProperty(object1,"hasOwnProperty"));
有一个方法叫做“hasOwnProperty”,它存在于对象上,但不建议直接调用该方法,因为有时可能会出现对象为空或某些属性存在于对象上的情况,例如:{ hasOwnProperty: false }
因此,更好的方式是:
// Good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));
// Best
const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));
使用反射的ECMAScript 6解决方案。创建一个类似于以下包装器:
/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
@param obj The object or array to be searched.
@param key The name of the property or key.
@param defVal Optional default version of the command-line parameter [default ""]
@return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
"use strict";
var retVal = (typeof defVal === 'undefined' ? "" : defVal);
if ( Reflect.has( obj, key) ) {
return Reflect.get( obj, key);
}
return retVal;
} // getSafeReflectArg
您需要使用方法object.hasOwnProperty(property)
。如果对象具有该属性,则返回true,否则返回false。
const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1'));
// expected output: true
console.log(object1.hasOwnProperty('toString'));
// expected output: false
console.log(object1.hasOwnProperty('hasOwnProperty'));
// expected output: false
当你可以这样做时,不要过于复杂化事情:
var isProperty = (objectname.keyname || "") ? true : false;
对于大多数情况来说,这是简单明了的...
const objectName = { keyname: false };
,它应该返回 true,因为 keyname
是 objectname
的一个属性。但是由于值是 false,根据这个逻辑它将返回 false。 - Wilt
Object.hasOwn
,它解决了Object.prototype.hasOwnProperty
的一些问题。 - Sebastian Simon