我正在尝试找出在Javascript应用程序中实现nextId()的最佳方法,该应用程序为其对象发布唯一ID。如果重要的话,这是一个我正在做的程序,作为纯JS,HTML和CSS(没有库,框架,DBMS等)的学习体验。我在这里看到了一个类似的问题(虽然我无法再找到它的链接),答案不仅包括存储与布尔值配对的可能ID列表以确定是否使用了id,还将已删除的ID存储在回收列表中,以用于将来需要它的对象。我认为后一种选择听起来更好,但我确信还有更多的方法可以做到这一点。有谁知道这项任务是否有模式,算法或其他最佳实践?
编辑: 我希望允许用户在应用程序生命周期的某个时刻共享数据,因此已存在的ID可能会在某些时候成为问题。我希望这些ID是永久性的,因为我将使用LocalStorage保存数据。一个简单的整数将起作用,我将用一两个字母前缀来标识对象的类型。填补空洞也很好,所以当用户长期使用它时,整数不会太高(一厢情愿)。
此外,所有对象都是在程序开头用字符串构造的(我知道它很疯狂)。
答案 0 :(得分:1)
如果你只需要一个页面生命周期唯一的id,你可以在页面中使用一个简单的单调增加计数器:
var getUniqueID = (function() {
var cntr = 0;
return function() {
return cntr++;
};
})();
var idA = getUniqueID();
var idB = getUniqueID();
确保您的ID在所有用户中都是唯一的,这是一项更高的任务。如果不涉及为您输入唯一ID的中央服务器,这里的一般概念是创建一个由三件事组合而成的id:
如果做得好,两个不同用户之间永远不会发生冲突(因为userID在id中)并且计数器使得没有用户在同一个会话中两次生成相同的id并且随机值产生赔率在相同的会话中自己生成相同id的用户非常小。
var getGUID = (function() {
var cntr = 0;
return function(userID) {
var rand = Math.random().toString().replace(".", "");
return userID + "_" + rand + "_" + cntr++;
};
})();
var idA = getGUID(myUserID);
var idB = getGUID(myUserID);
注意:这是GUID生成的更简单方法,假设您已经拥有userID。关于生成GUID的各种策略有很多研究和文献,如果你想要超出这个范围的话,你当然可以阅读更多。关于该主题的一些参考文献:
http://en.wikipedia.org/wiki/Globally_unique_identifier
http://betterexplained.com/articles/the-quick-guide-to-guids/
http://www.uddi.org/pubs/draft-leach-uuids-guids-01.txt
答案 1 :(得分:0)
根据用例,我想创建一个复杂的唯一ID:
function newGUID(){
var result = '';
var hexcodes = "0123456789abcdef".split("");
for (var index = 0; index < 32; index++) {
var value = Math.floor(Math.random() * 16);
switch (index) {
case 8:
result += '-';
break;
case 12:
value = 4;
break;
}
result += hexcodes[value];
}
return result;
}
答案 2 :(得分:0)
您可以将UUID用作ID。 There's one answer here in SO where you can generate UUIDs in JS。 UUID通常足以用作ID。只是为了确保id不是一个骗局,你可以拥有一个对象,其键是使用过的ID。生成ID时,您可以通过在对象中添加ID来跟踪它们。然后,您可以通过执行obj.hasOwnProperty(id)
来查找它们。
你可以这样做
var idStorage = {};
var id;
// generate ID that's unique and hasn't been used
do{
id = guid();
} while (idStorage.hasOwnProperty(id));
idStorage[id] = true;
// ID is usable
此外,ID应该是唯一的。它们永远不应该重复使用。
答案 3 :(得分:0)
AngularJS有一种非常简单的方法来生成唯一ID:只需增加一个全局计数器。来自src/Angular.js
:
var uid = 0;
// ...
/**
* A consistent way of creating unique IDs in angular.
*
* Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
* we hit number precision issues in JavaScript.
*
* Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
*
* @returns {number} an unique alpha-numeric string
*/
function nextUid() {
return ++uid;
}
当然,您应该选择一个解决方案,具体取决于生成的ID应该是唯一的时间范围。上述解决方案将生成对于一个网页的一个会话唯一的ID。对于一个简单的单页面应用程序(Angular的用例),这样做会很好。如果您需要它们在多个页面加载中是唯一的,或者对于同一个用户是唯一的,那么您需要将uid
保持更长时间(在cookie或数据库中)。如果他们需要在较长时间内保持唯一,您可能还需要查看长度超过2^53
的ID。
答案 4 :(得分:0)
我会使用UUID v4,因为这些ID在任何情况下都是唯一的(没有额外的逻辑可以检查这些ID是否正在使用或者用于修复旧ID),只需在需要时发出新ID
JS中非常简单的实现如下:
function generateUUID(){
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
$(function() {
$('button').bind('click', function() {
$('input').val(generateUUID());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" style="width: 350px;"/><button>GENERATE NEW ID</button>
答案 5 :(得分:0)
嗯,它有点不清楚你对这些ID的期望,但是如果你只想在你的系统中每种类型的实体都有一个唯一的id而你的数据只能存在于内存中,那么你可以使用以下方法:
注意:我从评论中看到你想要一个代表实体的前缀。
function identitySequence(base) {
var id = base || 0;
return function () {
return ++id;
};
}
//Lets say you had some sort of repository for every entity
function InMemoryUserRepository(nextId) {
this._nextId = nextId;
}
InMemoryUserRepository.prototype = {
constructor: InMemoryUserRepository,
get nextId() { return 'user-' + this._nextId(); }
//other operations, like save...
};
var userRepository = new InMemoryUserRepository(identitySequence());
userRepository.nextId; //user-1
现在,假设您希望您的ID序列在localStorage
中保持不变,您可以执行以下操作(扩展上述代码):
var userRepository = new InMemoryUserRepository(localStorageIdentitySequence('userIdSeq'));
userRepository.nextId; //user-1
//Reload page
userRepository.nextId; //user-2
function localStorageIdentitySequence(storageKey) {
var next = identitySequence(+localStorage.getItem(storageKey));
return function () {
return +(localStorage[storageKey] = next());
};
}
这适用于单台计算机,但是如果您想要一个可以跨机器生成唯一ID的唯一ID生成器,那么这种方法将无效。您必须从可以被所有客户端访问的服务器生成ID,或者您可以在客户端上生成GUID。无法知道GUID是否已由其他客户端生成,但这种可能性很小。