Ste*_*ini 110 javascript
我需要做一些实验,我需要知道javascript中对象的某种唯一标识符,所以我可以看看它们是否相同.我不想使用相等运算符,我需要类似python中的id()函数.
这样的事情存在吗?
Jus*_*son 62
更新我的原始答案是在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`
Run Code Online (Sandbox Code Playgroud)
如果您有古老的浏览器要求,请在此处查看浏览器兼容性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());
Run Code Online (Sandbox Code Playgroud)
请注意确保用于内部存储唯一ID的任何成员不会与另一个自动创建的成员名称冲突.
hak*_*shi 44
就我的观察而言,这里发布的任何答案都会产生意想不到的副作用.
在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
Run Code Online (Sandbox Code Playgroud)
Ale*_*tic 35
最新的浏览器为扩展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;
}
});
}());
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty
Kal*_*lEl 10
实际上,您不需要修改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;
}
Run Code Online (Sandbox Code Playgroud)
对于实现该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__;
}
};
})();
Run Code Online (Sandbox Code Playgroud)
@justin 答案的打字稿版本,与 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];
};
}
Run Code Online (Sandbox Code Playgroud)
用法示例:
console.log(Object.id(myObject));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
98581 次 |
最近记录: |