如何在javascript中修改不可配置的不可写属性?

时间:2016-12-09 22:34:49

标签: javascript events javascript-events event-handling

我正在写一个简单的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;
};

2 个答案:

答案 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