在 JavaScript 中将函数与 .toString() 进行比较
Comparing functions with .toString() in JavaScript
考虑片段
var dog1 = {id : 1, name : "Angus", age: 10};
var dog2 = {id : 1, name : "Angus", age: 10};
alert(dog1 == dog2); // ofcourse, false
alert(dog1.valueOf() == dog2.valueOf()); // ofcourse, false
在现实生活中,dog1 & dog2 将是同一个对象。
回到真实场景,
我最近从其他开发人员那里接手了这个项目,为了比较对象,他开发了以下函数来比较 2 个对象。该项目纯粹在JavaScript.
中开发
f() 检查两个对象是否相等 -
function compareObjs(obj1, obj2) {
var compare = function(objA, objB, param) {
var param_objA = objA[param];
var param_objB = (typeof objB[param] === "undefined") ? false : objB[param];
switch(typeof objA[param]) {
case "object": return (compareObjs(param_objA, param_objB));
case "function": return (param_objA.toString() === param_objB.toString());
default: return (param_objA === param_objB);
}
}; // internal compare helper function
for (var parameter_name in obj1)
if (typeof obj2[parameter_name] === "undefined" || !compare(obj1, obj2, parameter_name))
return false;
for (parameter_name in obj2)
if (typeof obj1[parameter_name] === "undefined" || !compare(obj1, obj2, parameter_name))
return false;
return true;
}
var dog1 = {name : "Angus",
bark : { frequency : "low" },
age: 10
};
var dog2 = {name : "Angus",
age: 10,
bark : { frequency : "low" }
};
alert(compareObjs(dog1,dog2)); // true
我对这一行感到困惑
case "function": return (param_objA.toString() === param_objB.toString());
为什么要检查函数相等性,他写了上面的代码?有人可以阐明这一点。方法正确吗?
原作者的想法可能是对象只有在具有相同功能的情况下才是相同的。
这是正确的方法吗?我不知道。对象相等性通常有两种有用的方式:成为相同的实例和具有相同的 content/values。这段代码添加了检查相同功能的元素,但我真的看不出这会有多大帮助。
您的前任是出于好意,但不幸的是,仅通过他们的文字来比较功能是不够的。您还必须考虑声明函数的环境,因为它可能使用闭包(在函数使用的函数外部定义的变量)。
看看这个例子:
function getOne() {
var x = 1;
return function foo() {
return x;
};
}
function getTwo() {
var x = 2;
return function foo() {
return x;
}
}
var f1 = getOne(),
f2 = getTwo();
console.log(f1 === f2); // false
console.log(f1.toString() === f2.toString()); // true
console.log(f1() === f2()); // false
在示例中,f1
和 f2
是具有完全相同的字符串表示形式的函数,但是一个函数在调用时是 returns 1
而另一个 returns 2
。所以正确比较函数的唯一方法是通过它们的引用,即 f1 === f2
.
考虑片段
var dog1 = {id : 1, name : "Angus", age: 10};
var dog2 = {id : 1, name : "Angus", age: 10};
alert(dog1 == dog2); // ofcourse, false
alert(dog1.valueOf() == dog2.valueOf()); // ofcourse, false
在现实生活中,dog1 & dog2 将是同一个对象。
回到真实场景,
我最近从其他开发人员那里接手了这个项目,为了比较对象,他开发了以下函数来比较 2 个对象。该项目纯粹在JavaScript.
中开发f() 检查两个对象是否相等 -
function compareObjs(obj1, obj2) {
var compare = function(objA, objB, param) {
var param_objA = objA[param];
var param_objB = (typeof objB[param] === "undefined") ? false : objB[param];
switch(typeof objA[param]) {
case "object": return (compareObjs(param_objA, param_objB));
case "function": return (param_objA.toString() === param_objB.toString());
default: return (param_objA === param_objB);
}
}; // internal compare helper function
for (var parameter_name in obj1)
if (typeof obj2[parameter_name] === "undefined" || !compare(obj1, obj2, parameter_name))
return false;
for (parameter_name in obj2)
if (typeof obj1[parameter_name] === "undefined" || !compare(obj1, obj2, parameter_name))
return false;
return true;
}
var dog1 = {name : "Angus",
bark : { frequency : "low" },
age: 10
};
var dog2 = {name : "Angus",
age: 10,
bark : { frequency : "low" }
};
alert(compareObjs(dog1,dog2)); // true
我对这一行感到困惑
case "function": return (param_objA.toString() === param_objB.toString());
为什么要检查函数相等性,他写了上面的代码?有人可以阐明这一点。方法正确吗?
原作者的想法可能是对象只有在具有相同功能的情况下才是相同的。
这是正确的方法吗?我不知道。对象相等性通常有两种有用的方式:成为相同的实例和具有相同的 content/values。这段代码添加了检查相同功能的元素,但我真的看不出这会有多大帮助。
您的前任是出于好意,但不幸的是,仅通过他们的文字来比较功能是不够的。您还必须考虑声明函数的环境,因为它可能使用闭包(在函数使用的函数外部定义的变量)。
看看这个例子:
function getOne() {
var x = 1;
return function foo() {
return x;
};
}
function getTwo() {
var x = 2;
return function foo() {
return x;
}
}
var f1 = getOne(),
f2 = getTwo();
console.log(f1 === f2); // false
console.log(f1.toString() === f2.toString()); // true
console.log(f1() === f2()); // false
在示例中,f1
和 f2
是具有完全相同的字符串表示形式的函数,但是一个函数在调用时是 returns 1
而另一个 returns 2
。所以正确比较函数的唯一方法是通过它们的引用,即 f1 === f2
.