몇 가지 실험을해야하고 자바 스크립트의 개체에 대한 고유 식별자를 알아야하므로 동일한 지 확인할 수 있습니다. 동등 연산자를 사용하고 싶지 않습니다. 파이썬의 id () 함수와 같은 것이 필요합니다.
이와 같은 것이 존재합니까?
답변
업데이트 아래 내 원래 답변은 6 년 전에 시대와 이해에 맞는 스타일로 작성되었습니다. 댓글의 일부 대화에 대한 응답으로 이에 대한보다 현대적인 접근 방식은 다음과 같습니다.
(function() {
if ( typeof Object.id == "undefined" ) {
var id = 0;
Object.id = function(o) {
if ( typeof o.__uniqueid == "undefined" ) {
Object.defineProperty(o, "__uniqueid", {
value: ++id,
enumerable: false,
// This could go either way, depending on your
// interpretation of what an "id" is
writable: false
});
}
return o.__uniqueid;
};
}
})();
var obj = { a: 1, b: 1 };
console.log(Object.id(obj));
console.log(Object.id([]));
console.log(Object.id({}));
console.log(Object.id(/./));
console.log(Object.id(function() {}));
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
console.log(k);
}
}
// Logged keys are `a` and `b`
구식 브라우저 요구 사항이있는 경우 여기 에서 Object.defineProperty
.
비교가 가치 있다고 생각하기 때문에 원래 답변은 (변경 내역이 아닌) 아래에 보관됩니다.
다음과 같은 스핀을 줄 수 있습니다. 또한 생성자 또는 다른 곳에서 객체의 ID를 명시 적으로 설정할 수있는 옵션도 제공합니다.
(function() {
if ( typeof Object.prototype.uniqueId == "undefined" ) {
var id = 0;
Object.prototype.uniqueId = function() {
if ( typeof this.__uniqueid == "undefined" ) {
this.__uniqueid = ++id;
}
return this.__uniqueid;
};
}
})();
var obj1 = {};
var obj2 = new Object();
console.log(obj1.uniqueId());
console.log(obj2.uniqueId());
console.log([].uniqueId());
console.log({}.uniqueId());
console.log(/./.uniqueId());
console.log((function() {}).uniqueId());
고유 ID를 내부적으로 저장하는 데 사용하는 구성원이 자동으로 생성 된 다른 구성원 이름과 충돌하지 않도록주의하십시오.
답변
내 관찰이 진행되는 한 여기에 게시 된 답변은 예기치 않은 부작용을 일으킬 수 있습니다.
ES2015 호환 환경에서 WeakMap 을 사용하여 부작용을 피할 수 있습니다 .
const id = (() => {
let currentId = 0;
const map = new WeakMap();
return (object) => {
if (!map.has(object)) {
map.set(object, ++currentId);
}
return map.get(object);
};
})();
id({}); //=> 1
답변
최신 브라우저는 Object.prototype을 확장하는 더 깨끗한 방법을 제공합니다. 이 코드는 속성 열거에서 속성을 숨 깁니다 (p in o).
defineProperty를 구현 하는 브라우저의 경우 다음 과 같이 uniqueId 속성을 구현할 수 있습니다.
(function() {
var id_counter = 1;
Object.defineProperty(Object.prototype, "__uniqueId", {
writable: true
});
Object.defineProperty(Object.prototype, "uniqueId", {
get: function() {
if (this.__uniqueId == undefined)
this.__uniqueId = id_counter++;
return this.__uniqueId;
}
});
}());
자세한 내용은 https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty를 참조 하십시오.
답변
실제로 object
프로토 타입 을 수정하고 거기에 함수를 추가 할 필요가 없습니다 . 다음은 귀하의 목적에 적합합니다.
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;
}
답변
Object.defineProperty()
메서드를 구현하는 브라우저의 경우 아래 코드는 소유 한 모든 개체에 바인딩 할 수있는 함수를 생성하고 반환합니다.
이 방법은 확장하지 않는 장점이 Object.prototype
있습니다.
코드는 주어진 객체에 __objectID__
속성 이 있는지 확인하고, 그렇지 않은 경우 숨겨진 (열거 불가능) 읽기 전용 속성으로 정의하여 작동합니다.
따라서 읽기 전용 obj.__objectID__
속성을 정의한 후 변경하거나 재정의하려는 시도에 대해 안전하며 조용히 실패하는 대신 지속적으로 멋진 오류를 발생시킵니다.
마지막으로, __objectID__
주어진 객체에 이미 다른 코드가 정의되어있는 매우 극단적 인 경우이 값은 단순히 반환됩니다.
var getObjectID = (function () {
var id = 0; // Private ID counter
return function (obj) {
if(obj.hasOwnProperty("__objectID__")) {
return obj.__objectID__;
} else {
++id;
Object.defineProperty(obj, "__objectID__", {
/*
* Explicitly sets these two attribute values to false,
* although they are false by default.
*/
"configurable" : false,
"enumerable" : false,
/*
* This closure guarantees that different objects
* will not share the same id variable.
*/
"get" : (function (__objectID__) {
return function () { return __objectID__; };
})(id),
"set" : function () {
throw new Error("Sorry, but 'obj.__objectID__' is read-only!");
}
});
return obj.__objectID__;
}
};
})();
답변
jQuery 코드는 data()
이러한 ID로 자체 메서드를 사용합니다 .
var id = $.data(object);
백 스테이지에서 메서드 data
는 다음과 같은 고유 ID 스트림의 다음 ID를 넣어 object
호출 하는 매우 특별한 필드를 만듭니다."jQuery" + now()
id = elem[ expando ] = ++uuid;
John Resig가 JavaScript에 대한 모든 것을 분명히 알고 있으며 그의 방법은 모든 지식을 기반으로하는 것과 동일한 방법을 사용하는 것이 좋습니다.
답변
@justin answer의 Typescript 버전, ES6 호환, Symbols를 사용하여 키 충돌을 방지하고 편의를 위해 전역 Object.id에 추가되었습니다. 아래 코드를 복사하여 붙여 넣거나 가져올 ObjecId.ts 파일에 넣으십시오.
(enableObjectID)();
declare global {
interface ObjectConstructor {
id: (object: any) => number;
}
}
const uniqueId: symbol = Symbol('The unique id of an object');
export function enableObjectID(): void {
if (typeof Object['id'] !== 'undefined') {
return;
}
let id: number = 0;
Object['id'] = (object: any) => {
const hasUniqueId: boolean = !!object[uniqueId];
if (!hasUniqueId) {
object[uniqueId] = ++id;
}
return object[uniqueId];
};
}
사용 예 :
console.log(Object.id(myObject));