以下是求职面试前JavaScript在线测试中的一个问题:
function F(){};
var a = new F();
var b = new F();
问:如何比较a == b
为true
? (例如console.log(a == b) // true
)
我回答说这是不可能的,因为a
和b
是F
的两个不同实例,并且在非基元的情况下JS中的相等比较比较参考。
但前段时间我已经读过Axel Rauschmayer撰写的文章“在JavaScript中假冒运算符重载”:http://www.2ality.com/2011/12/fake-operator-overloading.html - 我想知道在比较对象时是否存在伪造运算符重载的黑客攻击?
答案 0 :(得分:5)
这实际上取决于“如何比较a == b为真?”
如果允许更改构造函数,那么可以使构造函数成为单例:
function F(){
if (!F.instance) {
F.instance = this;
} else {
return F.instance;
}
};
var a = new F();
var b = new F();
if (a === b) {
//they are the same
}
如果他们希望您保持原样但包含a == b
的比较,那么您可以写下以下内容:
if ("" + a == b) {
}
如果他们想知道确定两个对象是否是同一构造函数的实例的方法,那么您可以比较constructor
属性或__proto__
属性:
if (a.constructor === b.constructor) {
}
if (a.__proto__ === b.__proto__) {
}
如果他们想知道dermine的方法这两个对象是否具有相同的属性,你可以比较他们的JSON字符串:
if (JSON.stringify(a) === JSON.stringify(b)) {
}
或者你编写一个递归比较两个对象中所有属性的函数(深度比较)。
关于“如何比较a == b是真的?”这个问题的最简单的答案:
var a = new F();
var b = new F();
b = a;
if (a === b) {
//surprise!!!
}
答案 1 :(得分:0)
我最好的答案就是这个,因为你可以比较不同的功能:
console.log(a.constructor+"" === b.constructor+"");
因为它将函数作为字符串返回,然后按字面比较它们。
示例测试:
function f1(){}
function f2(){}
var a = new f1(),
b= new f2();
console.log(a.constructor+"" === b.constructor+"");
b = new f1();
console.log(a.constructor+"" === b.constructor+"");
<强> DEMO 强>
注意:不需要===
符号,因为第三个符号用于类型比较,并且两者都是字符串,因此使用==
将完全相同的事情
编辑:我对该问题的实际答案是:从初始化中移除新