7

我试图发现一个对象是否具有某些属性并且我在使用 hasOwnProperty 方法时遇到了问题。

我在数组上使用该方法(我知道文档说明了一个字符串)。

以下行返回 true:

{ "a": 1, "b": 2 }.hasOwnProperty( ["a"]);

此行也返回 true:

{ "a": 1, "b": 2 }.hasOwnProperty( "a", "b");

但是这个返回false:

{ "a": 1, "b": 2 }.hasOwnProperty( ["a", "b"])

我需要它返回true。我正在使用 Object.keys(object) 来获取我正在使用的属性,它返回一个数组,所以我需要在 hasOWnProperty 上使用一个数组。

我缺少一些理论概念吗?有没有办法解决这个问题?

4

6 回答 6

17

这里有两件事。

首先,hasOwnProperty只接受一个论点。所以它会忽略你传递给它的任何其他参数。

其次,(我在这里稍微简化一下)它将第一个参数转换为String然后检查对象是否具有该属性。

所以让我们看看你的测试用例:

{ "a": 1, "b": 2 }.hasOwnProperty( "a", "b");返回的原因true是因为它忽略了第二个参数。所以实际上它只是检查“a”。

{ "a": 1, "b": 2 }.hasOwnProperty( ["a", "b"])返回false是因为第一个参数 ,["a", "b"]被转换为"a,b",并且没有{ "a": 1, "b": 2 }["a,b"].

要确定给定对象是否具有数组中的所有属性,您可以遍历数组并检查每个属性,如下所示:

function hasAllProperties(obj, props) {
    for (var i = 0; i < props.length; i++) {
        if (!obj.hasOwnProperty(props[i]))
            return false;
    }
    return true;
}

或者,如果您喜欢,可以使用该every函数隐式执行此操作:

var props = ["a", "b"];
var obj = { "a": 1, "b": 2 };
var hasAll = props.every(prop => obj.hasOwnProperty(prop));

我希望这有助于澄清事情。祝你好运!

于 2018-02-06T23:40:12.100 回答
2

如果要检查对象自身的属性,可以使用该Object.getOwnPropertyNames方法。它返回直接在给定对象上找到的所有属性的数组(包括不可枚举的属性,使用 Symbol 的属性除外)。

let o = { "a": 1, "b": 2 };
Object.getOwnPropertyNames(o).forEach(k => console.log(`key: ${k}, value: ${o[k]}`));

于 2018-02-06T23:34:44.100 回答
2

鉴于文档,该hasOwnProperty()方法似乎将字符串或符号作为参数。因此,我认为hasOwnProperty()无法获取字符串集合并测试对象是否将每个字符串都作为属性。

我认为另一种方法是获取字符串数组并遍历每个字符串。然后对于数组中的每个字符串(要测试的属性),您可以测试对象是否具有该属性。这是一个例子:

const o = new Object();
var propsToTest = ['a', 'b'];
o.a = 42;
o.b = 40;

var hasProperties = true;
propsToTest.forEach(function(element) {	// For each "property" in propsToTest, verify that o hasOwnProperty
  if(!o.hasOwnProperty(element))
    hasProperties = false;
});

console.log(hasProperties);

于 2018-02-06T23:39:54.597 回答
1

首先,就让您的第三个片段返回 true 而言,我认为这是不可能的。您可以做的最好的事情是单独检查每个属性:

const obj = { "a": 1, "b": 2 };
console.log(["a", "b"].every(p => obj.hasOwnProperty(p)))

哪个应该给你你想要的。


但是要理解为什么前两个返回 true,而第三个返回 false:

hasOwnProperty方法只接受一个参数(忽略其他参数),并且它期望该参数是一个字符串。如果参数不是字符串,那么 JavaScript 将尝试将其强制为一个(通常通过使用.toString方法)。

所以你的前两个片段是等价的,因为:

["a"].toString() === "a", so与参数转换为字符串后hasOwnProperty(["a"])相同。hasOwnProperty("a")

然后在您的第二个片段中,第二个参数"b"被简单地忽略,使其等同于hasOwnProperty("a")再次。

最后,您的第三个片段使用["a", "b"], 和["a", "b"].toString() === "a,b",这不是您的对象的属性。

于 2018-02-06T23:38:15.823 回答
0

您可以通过这样的for...in循环来实现这一点

const obj = { "a": 1, "b": 2 };

for (key in obj) {
        if (obj.hasOwnProperty(key)) {
           console.log('has', key, obj[key]);
        } else {
           console.log('not', key, obj[key]);
        }
}
于 2018-02-06T23:39:02.697 回答
0

所以这是一个老问题,我有点惊讶没有人想到写它,但这通常可以.every在数组上使用来解决。所以对于原始问题,代码应该是这样的:

["a", "b"].every((item) => ({ "a": 1, "b": 2 }.hasOwnProperty(item)))

这将返回一个简单的 true。Array.every将为数组中的每个项目运行一个条件,并且仅当条件对所有项目都为 true 时才返回 true。请参阅Mozilla 网络文档

于 2021-12-21T13:53:28.420 回答