初学者- Javascript中的深度比较
Beginner - Deep comparaison in Javascript
免责声明:我是JS的初学者
嗯,我正在阅读雄辩的Javascript,其中一个练习是深入比较JS中的对象。
对象定义如下:
var obj = {here: {is: "an"}, object: 2};
,你应该检查它们的内容是否相等。然后有3个测试:
console.log(deepEqual(obj, obj)); // supposed to return true
console.log(deepEqual(obj, {here: 1, object: 2})); // supposed to return false
console.log(deepEqual(obj, {here: {is: "an"}, object: 2})); // supposed to return true
这是我对深度相等方法的实现。为了简化,我假设比较的对象具有相同的结构,它们在现实生活中不会,但是我的方法应该返回false(我认为)
function deepEqual(obj1,obj2)
{
console.log("========");
for(prop in obj1)
{
console.log(prop);
if (typeof(prop)=="object" && prop!=null)
{
console.log("Inspecting object ", obj1[prop],obj2[prop]);
if (!deepEqual(obj1[prop],obj2[prop]))
{
return false;
}
}
else
{
console.log("Inspecting property ",prop,'[',obj1[prop],'][',obj2[prop],']');
if (obj1[prop]!=obj2[prop])
{
console.log("Different property");
return false;
}
}
}
return true;
}
var 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
分别返回true, false和....假!
输出如下:
========
here
Inspecting property here [ {is: "an"} ][ {is: "an"} ]
object
Inspecting property object [ 2 ][ 2 ]
true
========
here
Inspecting property here [ {is: "an"} ][ 1 ]
Different property
false
========
here
Inspecting property here [ {is: "an"} ][ {is: "an"} ]
Different property
false
有两件事我不明白:
- 为什么总是转到"检查属性"而从来不转到"检查对象"?{is: "an"}是一个对象,不是吗?
- 为什么"obj1[prop]!"=obj2[prop]" true,尽管,根据日志,它们都等于:{is: "an"} ?
供参考,书中的参考实现是:
function deepEqual(a, b) {
if (a === b) return true;
if (a == null || typeof a != "object" ||
b == null || typeof b != "object")
return false;
var propsInA = 0, propsInB = 0;
for (var prop in a)
propsInA += 1;
for (var prop in b) {
propsInB += 1;
if (!(prop in a) || !deepEqual(a[prop], b[prop]))
return false;
}
return propsInA == propsInB;
}
对我来说,第一个for循环只是计算A中有多少属性?我完全被第二个for循环(for (var prop in b))搞糊涂了…
编辑:非常感谢大家的回答!我不知道该接受哪一个,因为它们都对我帮助很大:-/prop
(在您的for (prop in obj)
循环中)不是一个值-它是一个键(MDN上的for in
循环)。当使用for in
循环时,您可以这样引用值:
for (var key in obj) {
var value = obj[key];
}
关于第二个问题:
为什么"obj1[prop]!"=obj2[prop]"是真的,尽管,根据日志,它们都等于:{is: "an"} ?
请注意,当比较两个对象(或任何其他非原语值)时,它们是通过引用来比较的,而不是通过值
来比较的。var obj1 = { name: true };
var obj2 = { name: true };
obj1 === obj2;
-> false (obj1 and obj2 are different objects)
var obj3 = { name: true };
var obj4 = obj3;
obj3 === obj4;
-> true (obj4 is basically a reference to obj3)
边注: javascript的一个好习惯是使用===
(严格比较)运算符而不是==
(抽象比较)。为什么?因为前者不会隐式地将比较值转换为其他类型。Javascript的类型转换不是那么明显,所以最好坚持使用更可预测的操作符。在JS中使用严格比较通常是更安全的比较方式。
您可以在MDN上阅读更多关于该主题的内容。
这一行不对:
if (typeof(prop)=="object" && prop!=null)
prop
是属性的键,它总是一个字符串,而不是属性的值。应该是:
if (typeof(obj1[prop])=="object" && obj1[prop]!=null)
我有一个很好的类比可以帮助解决这个问题:
为什么"obj1[prop]!"=obj2[prop]"是真的,尽管,根据日志,它们都等于:{is: "an"} ?
我和我哥哥可以说我们有同一个妈妈。
我和那边那个家伙可以说我们有相同的车,因为我们都有一辆黑色的丰田凯美瑞。
My Mother === My Brother's Mother // true, she is really the same person.
My car === Guy's car // false, looks the same but 2 different cars
obj !== {here: {is: "an"}, object: 2} // just looks the same
===为严格相等,如"3" === 3 // false
…和…
==忽略数据类型,如"3" == 3 // true
- 比较从函数和生成的日期对象
- 如何使用 node.js 比较两个 json 数组
- jQuery自定义验证比较多个输入的序列
- 反向字符串比较
- 通过JSON&比较时间
- 递归深度比较
- 与 lodash 进行对象深度比较的数组
- Javascript 深度比较
- 角度深度比较对象(特定属性除外)
- JS深度比较2个对象并删除在第二个对象中找到的项目,而不是第一个
- Javascript -深度相等比较
- 是否有一个实用程序来深度比较对象在谷歌闭包库
- 存储在Mongo中的数组无法与具有相同长度和值的本地javascript数组进行深度断言比较
- 初学者- Javascript中的深度比较
- Angular进行深度比较,并返回每一项的差值
- 使用JSON可以吗?Stringify用于深度比较和克隆
- 深度比较(Eloquent Javascript第4章):代码在测试用例中失败
- Javascript:深度比较
- 深度递归比较:对象和属性
- 这个柜台的功能是什么?雄辩的JavaScript 4.4深度比较的例子