我正在使用socketio 0.9来创建一个复杂的程序,为了存储所有的套接字id,我正在使用这样的数组:
var clients = {};
我正在使用自己的序列来识别我的套接字并将它们存储在我的阵列中,然后我设置了'套接字'关键,具有真正的价值。
clients[serial] = { "socket": socket.id };
现在我需要从我的数组中获取所有套接字ID而不使用它的序列号。我该怎么办?
我正在尝试使用此迭代,但我不知道如何获取套接字属性:
for(var c in clients) {
c.socket
}
感谢。
答案 0 :(得分:1)
虽然PHP称之为关联数组,但它只是JavaScript中的对象(也称为 hash ),而{{3理论计算机科学中的哈希映射。
话虽如此,for ... in
指令迭代对象的键,而不是值:
var clients = {
clientid1: { name: "John Doe", age: 42 },
clientid2: { name: "Jane Doe", age: 34 }
};
for (var key in clients) {
console.log(key);
}
Console output:
"clientid1"
"clientid2"
因此,要访问客户端哈希的值,例如socket
属性,请按以下方式迭代:
for (var serial in clients) {
clients[serial].socket.sendSomethingViaTheSocket(...);
}
for ... in
似乎有效,为什么其他解决方案甚至存在?由于JavaScript是一种非常具有hash table的dymanic语言,因此您可以添加,更改和删除几乎所有JavaScript对象的属性,并向对象原型添加新的属性和方法(所有方法的“蓝图”)和某个“类”的属性对象有)。
这意味着这是完全有效的JavaScript代码:
HTMLElement.prototype.isParagraph = false;
HTMLParagraphElement.prototype.isParagraph = true;
var myElement = document.querySelector(...);
if (myElement.isParagraph) {
// that's possible in javascript!
}
由于JavaScript中的大多数对象都允许扩展原型,因此Object
原型也是可能的,它是所有非值对象的祖先。假设您想要定义自己的方法来向对象添加属性(为什么您决定这样做):
Object.prototype.addProperty = function (name, value) {
this[name] = value;
};
var exampleCustomer = { name: "John Doe" };
exampleCustomer.addProperty("age", 42);
console.log(exampleCustomer.age); // logs 42 on the console
但这意味着从现在起, JavaScript中的每个对象都有addProperty
方法,因此当您使用for ... in
时,您将无法获得预期的结果:< / p>
for (var key in exampleCustomer) {
console.log('key ', key, ' equals ', exampleCustomer[key]);
}
Console output:
key name equals John Doe
key age equals 42
key addProperty equals function (name, value) { ... }
^ oops!
现在,您将发现for ... in
还会迭代要迭代的对象的原型链上设置的属性。这意味着使用for ... in
很好如果且仅当时,您可以确定没有人会改变您的原型。
从ES5开始,有两种方法可以缓解这个问题。认识prototypal inheritance和Object.defineProperty
。如果您需要在原型上定义方法,请使用以下方法:
Object.defineProperty(
Object.prototype, // the object the property should be defined on
"addProperty", // name of the property
{
enumerable: false, // should the property show up in for ... in / Object.keys()?
writable: true, // can the value of this property be changed with obj.addProperty = ..?
configurable: true, // can this property be changed with another defineProperty call?
value: function (name, value) { this[name] = value; }
}
);
使用configurable: false
定义属性时,不会显示在for ... in
循环中。
如果您不想使用库来解决上述问题,可以使用vanilla JavaScript中包含的一些方法。
Object.keys
和Array.prototype.forEach
:
Object.keys(clients).forEach(function (key) {
clients[key].socket.sendSomething();
});
// will NOT iterate over prototype-inherited properties
ECMAScript2015 / ECMAScript6 for ... of
:(适用于节点4+和新浏览器,无IE)
for (let clientid of clients) {
clients[clientid].socket.sendSomething();
}
//也不会迭代原型继承的属性
您还可以使用节点4+中的Array.prototype.map
和箭头功能以非常易读的方式获取所有客户端的套接字:
let clientSockets = Object.keys(clients).map(k => clients[k].socket);
// clientSockets contains the socket of all clients now
下划线/ lodash:
_.each(clients, function (client) {
client.socket.sendSomething();
});
jQuery的:
$.each(clients, function (id, client) {
client.socket.something();
});
AngularJS:
angular.forEach(clients, function (client, id) { // order is different than with jQuery!
client.socket.something();
});
答案 1 :(得分:0)
首先,clients
不是数组而是对象。
您可以使用Object.keys()
获取所有密钥,或者通过lodash
获得一些帮助,您可以使用_.keys
,或者如果您只对套接字ID感兴趣:
let _ = require('lodash');
console.log(_.map(clients, 'socket');
答案 2 :(得分:0)
您可以创建一个包含您保存的所有socketId的数组:
var arr = [];
Object.keys(clients).forEach(function(s){
arr.push(clients[s].socket)
});
console.log(arr); // arr would have all socketIds
这里Object.keys()返回客户端中所有连续出版物的数组,然后用于迭代并查找保存的每个socketId值