如何在JavaScript中修改不可配合的,不可误的属性



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

最新更新