我有一个对象,其中键是WebSockets(来自Node.JS ws
库)。
假设我有两个不同的WebSockets(" Socket A"和" Socket B")。
socketa === socketb // => false
套接字A是对象中唯一的键:
theObject.hasOwnProperty(socketa) // => true
问题在于:
theObject.hasOwnProperty(socketb) // => true
尽管这些是两个不同的对象(彼此!==
),但它们是对象中的 键,仅Socket A是的键
与key in object
相同的结果:
socketa in theObject // => true
socketb in theObject // => true
对象中肯定只有一个成员:
Object.keys(theObject).length // => 1
这里发生了什么?
答案 0 :(得分:2)
将属性分配给对象时,属性的键是字符串。如果您传递类似套接字的密钥,那么javascript将尽力将其转换为字符串并将其存储为密钥。如果WebSocket没有对转换为字符串的toString()
方法的特殊支持,那么您将获得一些通用转换,例如[object Object]
,这意味着所有WebSockets都将显示为相同的属性
当您查找密钥时,.hasOwnProperty()
也是如此。所以,你基本上会这样做:
theObject.hasOwnProperty("[object Object]")
所有套接字,因此它们看起来都一样。
您可以通过为套接字提供某种唯一ID然后使用它作为键来解决它,并且可以将套接字本身作为数据放在地图对象中。
例如,你可以这样做:
function addSocketToMap(socket, obj) {
if (!socket.uniqueKey) {
socket.uniqueKey = addSocketToMap.cntr++;
}
obj[socket.uniqueKey] = socket;
}
addSocketToMap.cntr = 0;
function isSocketInMap(socket, obj) {
if (socket.uniqueKey) {
return obj.hasOwnProperty(socket.uniqueKey);
}
return false;
}
var theObject = {};
addSocketToMap(socketA, theObject);
addSocketToMap(socketB, theObject);
var a = isSocketInMap(socketA, theObject); // true
var b = isSocketInMap(socketB, theObject); // true
如果这不会导致其实现出现任何问题,您也可能只是覆盖WebSocket对象的toString:
(function() {
var cntr = 0;
WebSocket.prototype.toString = function () {
// add a uniqueKey if it doesn't already exist
if (!this.uniqueKey) {
this.uniqueKey = cntr++;
}
// make a unique string identifier
// that will look like "WebSocket_xxx"
return "WebSocket_" + this.uniqueKey;
}
})();
答案 1 :(得分:0)
hasOwnProperty()
方法采用属性名称。如果WebSocket对象以相同的方式转换为字符串,它们都将满足hasOwnProperty(propName)
。因此,在两种情况下,属性 name 都在对象中。
编辑:
MDN reference for the in
operator.
MDN reference for the hasOwnProperty()
method
测试属性的两种方法都将使用属性 name 作为字符串,但hasOwnProperty()
不会像in
那样检查原型更改。
答案 2 :(得分:0)
hasOwnProperty
接受一个字符串参数,即属性的名称。你正在传递套接字,这不是你想要的。它应该定义为{"socket": socketa}
,然后测试theobject1["socket"] === theobject2["socket"]