以下代码(也在Plunker中)改编自this SO post。
我正在尝试实现相同的逻辑,只在uniqueId
的特殊属性中添加Object.prototype
函数以保持清晰。
以下代码在使用nodejs
运行时也有效(HTML-ized Plunker示例也可以)。即控制台打印三个唯一对象标识符:0
,1
和2
。
但是,当test
切换变量设置为1时,控制台会打印0
,0
和0
。
如何在uniqueId
命名空间中添加foo
函数?
function addUniqueId1(){
if (Object.prototype.foo===undefined) {
Object.prototype.foo = {};
console.log('foo "namespace" added');
}
if (Object.prototype.foo.uniqueId===undefined) {
var i = 0;
Object.prototype.foo.uniqueId = function() {
console.log('uniqueId function called');
if (this.___uniqueId === undefined) {
this.___uniqueId = i++;
}
return this.___uniqueId;
};
console.log('function defined');
}
}
function addUniqueId2() {
if (Object.prototype.uniqueId === undefined) {
var i = 0;
Object.prototype.uniqueId = function() {
if (this.___uniqueId === undefined) {
this.___uniqueId = i++;
}
return this.___uniqueId;
};
};
};
var test=2; // if you set this to 1 it stops working
if (test==1)
addUniqueId1();
else
addUniqueId2();
var xs = [{}, {}, {}];
for (var i = 0 ; i < xs.length ; i++) {
if (test==1)
console.log('object id is: ['+xs[i].foo.uniqueId()+']');
else
console.log('object id is: ['+xs[i].uniqueId()+']');
}
答案 0 :(得分:2)
您需要使用getter定义foo
,以允许它访问this
以便在子方法的散列中使用:
function defineFoo() {
if (Object.prototype.foo) return;
var i = 0;
Object.defineProperty(Object.prototype, 'foo', {
get: function() {
var self = this;
return {
uniqueId: function() {
return self.__uniqueId = self.uniqueId || ++i;
}
};
}
});
}
现在
defineFoo();
obj.foo.uniqueId()
如果您愿意,可以选择使用self
:
Object.defineProperty(Object.prototype, 'foo', {
get: function() {
return {
uniqueId: function() {
return this.__uniqueId = this.uniqueId || ++i;
}.bind(this)
};
}
});