我正在写一个简单的EventEmitter是ES5。
目标是确保EventEmitter
个实例上的所有属性都是
不可写和不可配置。“
经过6个小时的绞尽脑汁后,我仍然无法弄清楚如何增加listenerCount,例如configurable
描述符设置为false
。
以下是我所拥有的一个例子:
var eventEmitter = function(){
var listeners = listeners || 0;
var events = events || {};
Object.defineProperties(this, {
listeners: {
value : 0,
configurable: false,
writable: false
},
events: {
value: {},
configurable : false,
writable: false
}
});
return this;
};
eventEmmitter.prototype.on = function(ev, cb) {
if (typeof ev !== 'string') throw new TypeError("Event should be type string", "index.js", 6);
if (typeof cb !== 'function' || cb === null || cb === undefined) throw new TypeError("callback should be type function", "index.js", 7);
if (this.events[ev]){
this.events[ev].push(cb);
} else {
this.events[ev] = [cb];
}
this.listeners ++;
return this;
};
答案 0 :(得分:0)
我建议使用IIFE(即时调用的函数表达式):
var coolObj=(function(){
var public={};
var nonpublic={};
nonpublic.a=0;
public.getA=function(){nonpublic.a++;return nonpublic.a;};
return public;
})();
现在你可以做到:
coolObj.getA();//1
coolObj.getA();//2
coolObj.a;//undefined
coolObj.nonpublic;//undefined
coolObj.nonpublic.a;//undefined
我知道这不是你所期待的答案,但我认为这是最简单的做法。
答案 1 :(得分:0)
您可以使用需要密钥的代理来定义属性:
function createObject() {
var key = {configurable: true};
return [new Proxy({}, {
defineProperty(target, prop, desc) {
if (desc.value === key) {
return Reflect.defineProperty(target, prop, key);
}
}
}), key];
}
function func() {
var [obj, key] = createObject();
key.value = 0;
Reflect.defineProperty(obj, "value", {value: key});
key.value = function() {
key.value = obj.value + 1;
Reflect.defineProperty(obj, "value", {value: key});
};
Reflect.defineProperty(obj, "increase", {value: key});
return obj;
}
var obj = func();
console.log(obj.value); // 0
try { obj.value = 123; } catch(err) {}
try { Object.defineProperty(obj, "value", {value: 123}); } catch(err) {}
console.log(obj.value); // 0
obj.increase();
console.log(obj.value); // 1