code

자바 스크립트 개체 ID

codestyles 2020. 11. 2. 07:59
반응형

자바 스크립트 개체 ID


이 질문에 이미 답변이 있습니다.

JavaScript 객체 / 변수에 일종의 고유 식별자가 있습니까? Ruby가 object_id. 나는 DOM id 속성을 의미하는 것이 아니라 일종의 메모리 주소를 의미합니다.


아니요, 개체 프로토 타입을 수정하여 추가 할 수 있지만 개체에는 기본 제공 식별자가 없습니다. 다음은이를 수행하는 방법의 예입니다.

(function() {
    var id = 0;

    function generateId() { return id++; };

    Object.prototype.id = function() {
        var newId = generateId();

        this.id = function() { return newId; };

        return newId;
    };
})();

즉, 일반적으로 객체 프로토 타입을 수정하는 것은 매우 나쁜 습관으로 간주됩니다. 대신 필요에 따라 개체에 ID를 수동으로 할당하거나 touch다른 사람들이 제안한 기능을 사용하는 것이 좋습니다.


기본 개체를 수정하지 않고 고유 식별자를 사용하여 개체를 조회 / 연결하려면 다음을 사용할 수 있습니다 WeakMap.

// Note that object must be an object or array,
// NOT a primitive value like string, number, etc.
var objIdMap=new WeakMap, objectCount = 0;
function objectId(object){
  if (!objIdMap.has(object)) objIdMap.set(object,++objectCount);
  return objIdMap.get(object);
}

var o1={}, o2={}, o3={a:1}, o4={a:1};
console.log( objectId(o1) ) // 1
console.log( objectId(o2) ) // 2
console.log( objectId(o1) ) // 1
console.log( objectId(o3) ) // 3
console.log( objectId(o4) ) // 4
console.log( objectId(o3) ) // 3

를 사용 WeakMap하면 객체가 여전히 가비지 수집 될 수 있습니다.


실제로 object프로토 타입 을 수정할 필요가 없습니다 . 다음은 모든 개체의 고유 ID를 효율적으로 '얻기'위해 작동해야합니다.

var __next_objid=1;
function objectId(obj) {
    if (obj==null) return null;
    if (obj.__obj_id==null) obj.__obj_id=__next_objid++;
    return obj.__obj_id;
}

나는 방금 이것을 보았고 내 생각을 추가 할 것이라고 생각했습니다. 다른 사람들이 제안했듯이 수동으로 ID를 추가하는 것이 좋지만 실제로 설명한 내용과 가까운 것을 원한다면 다음을 사용할 수 있습니다.

var objectId = (function () {
    var allObjects = [];

    var f = function(obj) {
        if (allObjects.indexOf(obj) === -1) {
            allObjects.push(obj);
        }
        return allObjects.indexOf(obj);
    }
    f.clear = function() {
      allObjects = [];
    };
    return f;
})();

을 호출하여 모든 개체의 ID를 가져올 수 있습니다 objectId(obj). 그런 다음 ID가 객체의 속성이되도록하려면 프로토 타입을 확장 할 수 있습니다.

Object.prototype.id = function () {
    return objectId(this);
}

or you can manually add an ID to each object by adding a similar function as a method.

The major caveat is that this will prevent the garbage collector from destroying objects when they drop out of scope... they will never drop out of the scope of the allObjects array, so you might find memory leaks are an issue. If your set on using this method, you should do so for debugging purpose only. When needed, you can do objectId.clear() to clear the allObjects and let the GC do its job (but from that point the object ids will all be reset).


Using ES6 + Symbols.

Use ES6 Module export for Symbol if unique symbol is preferred, otherwise go with Symbols in global registry.

(function () {
    let id = 0;
    const generateId = () => ++id;

    // export const identifier = Symbol('identifier'); //unique symbol
    const identifier = Symbol.for('identifier'); //symbol in global registry

    Object.prototype[identifier] = function () {
        const id = generateId();
        this.id = this.id || id;
        return this.id;
    };

})();

참고URL : https://stackoverflow.com/questions/2020670/javascript-object-id

반응형