Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Improve 'method' functionality.

- Proto chain safe
- Memoized method is ready right after first access (previously it was bundled on first invokation which was problematic)
- memoize when used with method option returns object with name -> descriptor content, it should be used with Object.defineProperties on target object
  • Loading branch information...
commit fb4439692df37203e539054886ce18101fcbfc39 1 parent 0e32a47
@medikoo authored
View
1  .lint
@@ -11,7 +11,6 @@ jslint_medikoo.nomen
jshint.laxcomma
jshint.camelcase
-jshint.curly
jshint.eqeqeq
jshint.forin
jshint.immed
View
10 lib/_base.js
@@ -13,12 +13,14 @@ module.exports = exports = function (core) {
var options, length, get, clear, conf;
callable(fn);
- if (fn.memoized) {
- // Do not memoize already memoized function
- return fn;
- }
+ // Do not memoize already memoized function
+ if (fn.memoized) return fn;
options = Object(arguments[1]);
+ if (ext.method && (options.method != null)) {
+ return ext.method(options.method, options, fn, self);
+ }
+
conf = ee({ memoize: self, fn: fn });
// Normalize length
View
7 lib/ext/dispose.js
@@ -9,19 +9,20 @@ var callable = require('es5-ext/lib/Object/valid-callable')
, slice = Array.prototype.slice;
ext.dispose = function (dispose, conf, options) {
- var clear, async;
+ var clear, async, context;
callable(dispose);
async = (options.async && ext.async);
+ context = options.context;
conf.on('purge' + (async ? 'async' : ''), clear = async ? function (id) {
var value = conf.async[id];
delete conf.cache[id];
- dispose.apply(conf.memoized['_memoize:context_'], slice.call(value, 1));
+ dispose.apply(context, slice.call(value, 1));
} : function (id) {
var value = conf.cache[id];
delete conf.cache[id];
- dispose.call(conf.memoized['_memoize:context_'], value);
+ dispose.call(context, value);
});
if (!async) {
View
63 lib/ext/method.js
@@ -2,38 +2,41 @@
'use strict';
-var d = require('es5-ext/lib/Object/descriptor')
- , global = require('es5-ext/lib/global')
- , extend = require('es5-ext/lib/Object/extend')
- , isString = require('es5-ext/lib/String/is-string')
+var copy = require('es5-ext/lib/Object/copy')
- , create = Object.create, defineProperty = Object.defineProperty;
+ , defineProperty = Object.defineProperty;
-require('../_base').ext.method = function (method, conf, options) {
- if (isString(options.method)) {
- method = { name: String(options.method),
- descriptor: { configurable: true, writable: true } };
- } else {
- method = options.method;
- method.name = String(method.name);
- method.descriptor = (method.descriptor == null) ?
- { configurable: true, writable: true } : Object(method.descriptor);
+require('../_base').ext.method = function (method, options, fn, configure) {
+ var name, descriptor, props, prop, selfName;
+ name = selfName = String(method);
+ descriptor = {
+ enumerable: (options.enumerable == null) ? false :
+ Boolean(options.enumerable),
+ configurable: (options.configurable == null) ? true :
+ Boolean(options.configurable),
+ writable: (options.writable == null) ? true :
+ Boolean(options.writable)
+ };
+ props = {};
+ prop = props[selfName] = copy(descriptor);
+ delete prop.writable;
+ if (options.protoDeep != null) {
+ if (typeof options.protoDeep === 'boolean') {
+ if (options.protoDeep) name = '_' + name + '_';
+ } else {
+ name = String(options.protoDeep);
+ }
}
- options = create(options);
- options.method = undefined;
+ options = copy(options);
+ delete options.method;
+ delete options.protoDeep;
- (function (fn) {
- conf.memoized = function () {
- var memoized;
- if (this && (this !== global)) {
- memoized = method.descriptor.value =
- conf.memoize(conf.fn.bind(this), options);
- defineProperty(this, method.name, method.descriptor);
- defineProperty(memoized, '_memoize:context_', d(this));
- return memoized.apply(this, arguments);
- }
- return fn.apply(this, arguments);
- };
- extend(conf.memoized, fn);
- }(conf.memoized));
+ prop.get = function () {
+ if ((name !== selfName) && this.hasOwnProperty(name)) return this[name];
+ options.context = this;
+ descriptor.value = configure(fn, options);
+ defineProperty(this, name, descriptor);
+ return this[name];
+ };
+ return props;
};
View
2  package.json
@@ -1,6 +1,6 @@
{
"name": "memoizee",
- "version": "0.2.3",
+ "version": "0.3.0",
"description": "Complete memoize/cache solution. Works with any type and length of function arguments",
"main": "lib",
"scripts": {
View
4 test/ext/dispose.js
@@ -47,10 +47,10 @@ module.exports = function () {
++i;
return x + y;
};
- Object.defineProperty(value, 'mfn', { value: memoize(fn, {
+ Object.defineProperties(value, memoize(fn, {
method: 'mfn',
dispose: function (val) { this.push(val); }
- }), configurable: true });
+ }));
value.mfn(3, 7);
value.mfn(5, 8);
View
14 test/ext/method.js
@@ -5,25 +5,25 @@ var memoize = require('../../lib');
module.exports = function () {
return {
"No descriptor": function (a) {
- var mfn, x = {}, i = 0, fn = function () {
+ var x = {}, i = 0, fn = function () {
++i;
return this;
};
- mfn = memoize(fn, { method: 'foo' });
- a(mfn.call(x), x, "Context");
+ Object.defineProperties(x, memoize(fn, { method: 'foo' }));
+ a(x.foo(), x, "Context");
a(x.foo(), x, "Method");
a(i, 1, "Cached");
},
"Descriptor": function (a) {
- var mfn, x = {}, i = 0, fn = function () {
+ var x = {}, i = 0, fn = function () {
++i;
return this;
};
- mfn = memoize(fn,
- { method: { name: 'foo', descriptor: { configurable: true } } });
- a(mfn.call(x), x, "Context");
+ Object.defineProperties(x, memoize(fn,
+ { method: 'foo', writable: false }));
+ a(x.foo(), x, "Context");
a.deep(Object.getOwnPropertyDescriptor(x, 'foo'),
{ enumerable: false, configurable: true, writable: false,
value: x.foo });
View
14 test/index.js
@@ -212,25 +212,25 @@ module.exports = function (t, a) {
},
"Method": {
"No descriptor": function (a) {
- var mfn, x = {}, i = 0, fn = function () {
+ var x = {}, i = 0, fn = function () {
++i;
return this;
};
- mfn = t(fn, { method: 'foo' });
- a(mfn.call(x), x, "Context");
+ Object.defineProperties(x, t(fn, { method: 'foo' }));
+ a(x.foo(), x, "Context");
a(x.foo(), x, "Method");
a(i, 1, "Cached");
},
"Descriptor": function (a) {
- var mfn, x = {}, i = 0, fn = function () {
+ var x = {}, i = 0, fn = function () {
++i;
return this;
};
- mfn = t(fn,
- { method: { name: 'foo', descriptor: { configurable: true } } });
- a(mfn.call(x), x, "Context");
+ Object.defineProperties(x, t(fn,
+ { method: 'foo', writable: false }));
+ a(x.foo(), x, "Context");
a.deep(Object.getOwnPropertyDescriptor(x, 'foo'),
{ enumerable: false, configurable: true, writable: false,
value: x.foo });
Please sign in to comment.
Something went wrong with that request. Please try again.