我正在尝试创建一个JavaScript函数来查看对象数组(第一个参数)并返回一个包含匹配的属性和值对的所有对象的数组。
虽然在freeCodeCamp给出了正确的解决方案,但我想知道我的代码中存在哪些问题和错误。另外,我找到了堆栈溢出的解决方案,但我的代码没有出错。
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
var obj;
var prop;
var keys = Object.keys(source);
for (var i = 0; i < collection.length; i++) {
for (var j = 0; j < Object.keys(source).length; j++) {
obj = collection[i];
prop = Object.keys(source)[j];
if (obj.hasOwnProperty(prop) && obj.prop === source.prop) {
arr = arr.concat([obj]);
}
}
}
// Only change code above this line
return arr;
}
whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
以下是我得到的结果
[{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }]
而不是
[{ first: "Tybalt", last: "Capulet" }]
答案 0 :(得分:4)
在 if -statement中,您需要obj[prop] === source[prop]
而不是obj.prop === source.prop
。请参阅computed property names。
由于两个对象都不包含属性prop
,因此条件总是评估为true
(undefined === undefined
为true
)。
演示
(注意我将obj = collection[i];
移动到外部循环,因为它是多余的,每次都在内部循环中分配它)
function whatIsInAName(collection, source) {
// What's in a name?
var arr = [];
// Only change code below this line
var obj;
var prop;
var keys = Object.keys(source);
for (var i = 0; i < collection.length; i++) {
obj = collection[i];
for (var j = 0; j < Object.keys(source).length; j++) {
prop = Object.keys(source)[j];
if (obj.hasOwnProperty(prop) && obj[prop] === source[prop]) {
arr = arr.concat([obj]);
}
}
}
// Only change code above this line
return arr;
}
let res = whatIsInAName([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" });
console.log(res)
&#13;
答案 1 :(得分:1)
[Kristianmitk显然在我写这篇文章的同时添加了一些解释,但是我也会在这里留下这个答案,以防替代解释对任何人都有用......]
Kristianmitk说的是正确的,但也许可以使用一些解释。
您的代码返回每个元素的原因是,在每种情况下,您最终都会检查
if (/*...*/ && obj.prop === source.prop) {
//...
}
但obj.prop
表示&#34;名为prop
&#34;的属性;也就是说,你会用它来找到价值&#34; xyzzy&#34;一个声明为
{ prop: "xyzzy" }
您想要检查由变量prop 的值命名的属性。这是使用[]
运算符完成的。
var prop = "foo";
var obj = { prop: "nope" , foo: "found it" };
// these are true:
obj.prop === "nope"
obj[prop] === "found it"
在您的测试用例中,由于所讨论的对象都没有prop
属性,因此所有值均为undefined
。而且因为JavaScript是动态的,引用这些未定义的值(没有错误)是很好的。因为JavaScript是由异教徒编写的,undefined === undefined
是true
。
还有其他方法可以改进代码(为了便于阅读),但我认为这是唯一能够使代码无法正常工作的方法。接下来我要看的是,即使你已经说过了
var keys = Object.keys(source);
如果您只是说Object.keys(source)
,那么您稍后会再次拨打keys
来拨打电话。正如一些人所声称的那样,这不是一个有效的问题&#34;。有一次使用变量肯定更有效率,也许它仍然是,但关心在该级别的优化并不是一个好主意。但是,关注可读性是一个好主意,一旦你给keys
数组一个漂亮,简单的名称(keys
),你应该使用它。