Skip to main content
Tweeted twitter.com/#!/StackCodeReview/status/640260341650313216
deleted 85 characters in body
Source Link
Jamal
  • 34.9k
  • 13
  • 133
  • 237

Please find my implementation of a LRU Cache in ECMAScript attached. I wrote itthis for a CodeWars challenge while trying to learn ECMAScript and would really like to have some advice on how it could be improved.

  • I didn't yet found a way to have a class in ECMAScript that mixes public and private methods in a way, where the public methods (and only them) can still access private methods and vars.
  • (Partly caused by the point above) I think the code is way totoo verbose and bloated. Too much of it is wasted inon language specific implementation details. There must be a smarter way to do this - I feel like I could write the same functionality in PHP using 10% of the lines I needed now.

Code:

Please find my implementation of a LRU Cache in ECMAScript attached. I wrote it for a CodeWars challenge while trying to learn ECMAScript and would really like to have some advice on how it could be improved.

  • I didn't yet found a way to have a class in ECMAScript that mixes public and private methods in a way, where the public methods (and only them) can still access private methods and vars.
  • (Partly caused by the point above) I think the code is way to verbose and bloated. Too much of it is wasted in language specific implementation details. There must be a smarter way to do this - I feel like I could write the same functionality in PHP using 10% of the lines I needed now.

Code:

I wrote this for a CodeWars challenge while trying to learn ECMAScript and would really like to have some advice on how it could be improved.

  • I didn't yet found a way to have a class in ECMAScript that mixes public and private methods in a way, where the public methods (and only them) can still access private methods and vars.
  • (Partly caused by the point above) I think the code is way too verbose and bloated. Too much of it is wasted on language specific implementation details. There must be a smarter way to do this - I feel like I could write the same functionality in PHP using 10% of the lines I needed now.
edited tags
Link
Vogel612
  • 25.3k
  • 7
  • 58
  • 141
Source Link
s1lv3r
  • 143
  • 3

LRU Cache in ECMAScript

Please find my implementation of a LRU Cache in ECMAScript attached. I wrote it for a CodeWars challenge while trying to learn ECMAScript and would really like to have some advice on how it could be improved.

What I don't like about this code myself, but am unsure on how to improve:

  • I didn't yet found a way to have a class in ECMAScript that mixes public and private methods in a way, where the public methods (and only them) can still access private methods and vars.
  • (Partly caused by the point above) I think the code is way to verbose and bloated. Too much of it is wasted in language specific implementation details. There must be a smarter way to do this - I feel like I could write the same functionality in PHP using 10% of the lines I needed now.

Code:

function LRUCache(capacity, init) {

  this._capacity = capacity;
  this._size = 0;
  this._accessMap = [];
  this._items = [];
  this._frozenMethods = ['cache', 'delete'];  
  this._functionalProps = ['size', 'capacity'];

  this.cache = function(key, value) {
    
    if( this._accessMap.indexOf(key) == -1 ) {
      this._addNewItem(key);
    }
    
    this._items[key] = this[key] = value;
    this._updateAccessMap(key);
    
    return this;
  },
  this.delete = function(key) {
  
    if(this._frozenMethods.indexOf(key) !== -1 ||
    this._functionalProps.indexOf(key) !== -1) {
      return false;
    }
    
    if( this._accessMap.indexOf(key) === -1 ) {
      return true;
    }

    delete this[key];
    delete this._items[key];
    this._size--;

    this._updateAccessMap(key, true);

    return true;
  },
  this._removeOldest = function() {
    var key = this._accessMap[0];
    
    this.delete(key);
  },
  this._updateAccessMap = function(key, remove) {

    index = this._accessMap.indexOf(key);
        
    if( index !== -1) {
      this._accessMap.splice(index, 1);
    }
      
    if(!remove) {
      this._accessMap.push(key);
    }
  },
  this._addNewItem = function(key) {

    this._size++;
    
    if(this._size > this._capacity) {
      this._removeOldest();
    }
    
    Object.defineProperty(this, key, {
      get: function() {
        this._updateAccessMap(key);
        
        return this._items[key];
      },
      set: function(v) {
        this._items[key] = v;
        this._updateAccessMap(key);
        return this;
      },
      enumerable: true,
      configurable: true
    });
  };
  
  var obj = this;
  
  this._frozenMethods.map( function(v) {
    Object.defineProperty(obj, v, {
      enumerable: false,
      writable: false,
      configurable: false
    });
  });

  ['_items', '_capacity', '_accessMap', '_frozenMethods','_size', '_functionalProps',
  '_removeOldest','_updateAccessMap','_addNewItem'].map( function(v) {
    Object.defineProperty(obj, v, {
      enumerable: false,
      configurable: true
    });
  });

  Object.defineProperty(this, 'capacity', {
    set: function(v) {
    
      while(this.size > v) {
        this._removeOldest();
      }
      
      this._capacity = v;
    },
    get: function() {
      return this._capacity;
    },
    configurable: false
  });
  

  Object.defineProperty(this, 'size', {
    set: function(v) {
      return false;
    },
    get: function() {
      return this._size;
    },
    configurable: false
  });
  
  if(init) {
    for(var attr in init) {
      if( !init.hasOwnProperty(attr) ) {
        continue;
      }
      this.cache(attr, init[attr]);
    }
  }
}