有说服力的Javascript练习:深入比较
我正在学习JavaScript并尝试做以下练习: 编写一个函数有说服力的Javascript练习:深入比较,javascript,object,Javascript,Object,我正在学习JavaScript并尝试做以下练习: 编写一个函数deepEqual,该函数接受两个值并仅当它们是相同的值或具有相同属性的对象时返回true,其中 与对deepEqual的递归调用相比,这些属性的个数相等 要确定是否应直接比较值(请使用=运算符 为此,您可以使用typeof运算符来比较它们的属性。 如果它为这两个值生成“object”,则应该进行深入比较。 但你必须考虑一个愚蠢的例外:因为一个历史事件 意外情况下,typeof null也会产生“object” 当您需要查看属性时,O
deepEqual
,该函数接受两个值并仅当它们是相同的值或具有相同属性的对象时返回true
,其中
与对deepEqual
的递归调用相比,这些属性的个数相等
要确定是否应直接比较值(请使用=
运算符
为此,您可以使用typeof
运算符来比较它们的属性。
如果它为这两个值生成“object”,则应该进行深入比较。
但你必须考虑一个愚蠢的例外:因为一个历史事件
意外情况下,typeof null
也会产生“object”
当您需要查看属性时,Object.keys
功能将非常有用
要比较它们的对象的数量
这是我的解决方案,给了我true
,false
,false
,这是错误的
function deepEqual (a,b) {
if (a===b) return true;
if (typeof a=="object" && typeof b=="object") {
let x=Object.keys(a), y=Object.keys(b);
if (x.lenght==y.lenght) {
for (key of x){
if (y.includes(key)){
if (a[key]===b[key]) return true;
else return false;
}
}
}
return true;
}
}
let obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
console.log(deepEqual(obj, {here: 1, object: 2}));
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
这是正确的解决方案:
function deepEqual(a, b) {
if (a === b) return true;
if (a == null || typeof a != "object" ||
b == null || typeof b != "object") return false;
let keysA = Object.keys(a), keysB = Object.keys(b);
if (keysA.length != keysB.length) return false;
for (let key of keysA) {
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
}
return true;
}
let obj = {here: {is: "an"}, object: 2};
console.log(deepEqual(obj, obj));
// → true
console.log(deepEqual(obj, {here: 1, object: 2}));
// → false
console.log(deepEqual(obj, {here: {is: "an"}, object: 2}));
// → true
我真的不明白我写的东西到底出了什么问题,我该如何修复它
非常感谢您帮助noobie:)以下是您代码中的问题: 1)对象的测试:
if (typeof a=="object" && typeof b=="object") {
这很好,但是如果这个条件不是真的呢?您没有任何处理这种情况的代码,因此函数将返回undefined
。它应该返回false
其次,JavaScript中有一个奇怪的东西,这个问题已经警告过你——你应该考虑到它:
…由于历史事故,typeof null
也会生成“object”
…因此您需要对此进行单独的测试,因为null
不是真正的对象,当您将其视为一个对象时,代码将产生错误
在您的代码中,一个null
值将通过此if
测试,然后将执行Object.keys(null)
,这将触发异常。此处不允许有null
值
2)比较属性的数量
if (x.lenght==y.lenght) {
if (y.includes(key)){
有一个拼写错误。它不是长度
,而是长度
(2x)。
再说一次,如果这个条件不是真的呢?没有处理这种情况的代码,除了在if
块之后的返回true
之外,但是您的函数应该返回false
3)检查两个对象中是否存在属性
if (x.lenght==y.lenght) {
if (y.includes(key)){
此测试有效,但不是最佳测试includes
比只检查是否键入b
慢(遗憾的是,参考解决方案也使用includes
)
和以前一样,如果这个条件不成立怎么办?函数应该立即退出循环并返回false
,但这不会发生
4)检查相同属性的值是否完全相等。
if (a[key]===b[key]) return true;
这种情况并不能进行深入的比较。问题已经告诉您在这里该做什么:
…与递归调用deepEqual
因此,在这种情况下,您应该执行递归调用,以便以相同的方式比较任何嵌套对象。当这两个值是单独的对象时,仅a[key]===b[key]
将为false
。但是当这些对象具有相同的属性和相同的值时,条件实际上应该是true
。。。这正是函数所能做的:所以在这里调用它
其次,现在不是返回true的时候,因为这将在不检查其他键的情况下退出循环,结果可能是否定的。。。一个“否定”就足以使整个最终结果为假。所以,当事情进展顺利时,你应该继续循环
5)当值不同时
else return false;
是的,现在正是返回false的正确时间
6)当所有测试成功时
return true;
这是返回true的唯一正确位置,但是您应该解决我答案中的第二个备注,以便在长度不同时不执行此语句
正确的代码
由于您已经有了正确的代码可供比较,因此在此处重复该代码有点过头了。您没有深入研究嵌套对象;这是一个典型的递归问题<代码>长度
拼写错误。我尝试了:函数deepEqual(a,b){if(a==b)返回true;if(a的类型==“object”&&typeof b==“object”){let x=object.keys(a),y=object.keys(b);if(x.lenght==y.lenght){for(x的键){if(y.includes(key)){if(a[key]==b[key])return true;else return false;}}}}}return true;else return false;}else return false;}let obj={here:{is:“an”},object:2};控制台日志(deepEqual(obj,obj))代码>但仍然不起作用..这是难以辨认的注释<代码>长度
仍然拼写错误,并且仍然没有深入到嵌套对象中。请中断解决方案并映射到您编写的内容。你会很容易看出你的解决方案在哪些方面都不正确。你帮了我很多,非常感谢!我改成这样,但仍然不起作用:code
function deepEqual(a,b){if(a==b)返回true;if(typeof a==null | | typeof b==null)返回false;else{if(typeof a==“object”&&typeof b==“object”){let x=object.keys(a),y=object.keys(b);if(x.length==y.length){for(key of x的键){if(y.includes键)){if(deepEqual(a[key],b[key]);else返回false;}返回true;else返回false;}返回true;else返回false;}返回true;else返回false;