我正在写一个简单的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;
};
我建议使用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
我知道这不是您预期的答案,但我认为这是这样做的最简单的方法。
您可以使用需要键来定义属性的代理:
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