const log = console.info
let fn, fn1, fn2, val, val1, val2
function foo(...args) {
this.a && log('this.a:' + this.a)
return args.reduce((tol, cur) => tol + cur)
}
Function.prototype._apply = function (obj, args) {
obj = obj ? Object(obj) : global;
const fn = Symbol()
obj[fn] = this
const result = obj[fn](...args)
delete obj[fn]
return result
}
log(foo._apply({ a: 1 }, [2, 3]))
Function.prototype._call = function (obj, ...args) {
return this._apply(obj, args)
}
log(foo._call({ a: 1 }, 2, 3))
log(foo._call(null, 2))
Function.prototype._bind = function (obj, ...args) {
let self = this
return function (...rest) {
return self._call(obj, ...args, ...rest)
}
}
fn = foo._bind({ a: 1 }, 2, 3);
log(fn(4))
const _ = {}
Function.prototype._partial = function (...args) {
let self = this
return function (...rest) {
let i = 0
args = args.map(item => item === _ ? rest[i++] : item)
return self._call(this, ...args, ...rest.slice(i))
}
}
fn2 = (x, y) => x + y
log(foo._partial(_, 2)())
log(fn2(3, 1, 1))
Function.prototype._thunk = function (...args) {
let self = this
return function (...rest) {
return self._call(this, ...args, ...rest)
}
}
Function.prototype._thunktopromise = function () {
let self = this
return new Promise(function (resolve, reject) {
self(function (data) {
if (data.err) return reject(data.err);
resolve(data.res ? data.res : data)
});
});
}
fn = x => cb => cb(x)
fn1 = (x, cb) => cb(x)
var gen = function* () {
log('gen-in')
var r1 = yield fn(100);
log('r1:', r1)
var r2 = yield fn1._thunk(r1);
return r1 + r2
};
function thunkCo(fn) {
var gen = fn();
function next(data) {
log('run-in')
var result = gen.next(data);
log(data, result)
if (result.done) return result.value
return result.value(next);
}
return next();
}
fn = x => Promise.resolve(x)
gen = function* () {
log('gen-in')
var r2 = yield fn1._thunk(100)._thunktopromise();
log('r2:', r2)
var r1 = yield fn(100);
log('r1:', r1)
return r1 + r2
};
function promiseCo(fn) {
var gen = fn();
function next(data) {
log('run-in')
var result = gen.next(data);
log(data, result, result.done)
if (result.done) return result.value
return result.value.then(next);
}
return next();
}
Array.prototype._iterator = function () {
let array = this;
let i = 0;
return {
next: function () {
return i < array.length ?
{ value: array[i++], done: false } :
{ value: undefined, done: true };
}
};
}
let it = [1, 2]._iterator()
Function.prototype._reduxThunk = (middleApi) => (next) => (action) => {
if (typeof action == 'function') {
console.log(1);
return action(middleApi.dispatch, middleApi.getState);
}
console.log(2);
return next(action);
}
var incAsy = () => (dispatch) => {
console.log('等待2秒');
setTimeout(() => {
dispatch({ type: 'xxx' });
},
2000);
}
function iteratorCo(gen) {
function toPromise(obj) {
if ('function' == typeof obj) return thunkToPromise.call(this, obj);
if (isGeneratorFunction(obj) || isIterator(obj)) return Promise.resolve().then(() => iteratorCo.call(this, obj));
function isIterator(obj) {
return 'function' == typeof obj.next && 'function' == typeof obj.throw;
}
function isGeneratorFunction(obj) {
let constructor = obj.constructor;
if (!constructor) return false;
if (constructor.name === 'GeneratorFunction' || constructor.displayName === 'GeneratorFunction') return true;
return isIterator(obj);
}
function thunkToPromise(fn) {
var ctx = this;
return new Promise(function (resolve, reject) {
fn.call(ctx, function (err, res) {
if (err) return reject(err);
if (arguments.length > 2) res = slice.call(arguments, 1);
resolve(res);
});
});
}
return obj
}
if (typeof gen === 'function') gen = gen();
function next(data) {
log('run-in', gen)
var result = gen.next(data);
log('run-in-result', data, result)
if (result.done) return result.value
let value = toPromise(result.value)
log('value', value)
return value.then(next);
}
return next();
}
function koa_compose(middleware) {
return function* (next) {
if (!next) next = () => { };
var i = middleware.length;
while (i--) {
next = middleware[i].call(this, next);
}
return yield* next;
}
}
gen = koa_compose([
function* (next) { log('1-start'); yield next; log('1-end') },
function* (next) { log('2-start'); yield next; log('2-end') },
function* (next) { log('3-start-end'); },
])
function koa2_compose(middleware) {
return function (ctx) {
function dispatch(i) {
const fn = middleware[i]
if (!fn) return Promise.resolve()
try {
return Promise.resolve(
fn(ctx, () => dispatch(i + 1))
)
} catch (err) {
return Promise.reject(err)
}
}
return dispatch(0)
}
}
Function.prototype._curry = function (...args) {
let self = this
let len = self.length;
log(args.length, len, args)
if (!args.some(item => item === _) && args.length >= len) return self.call(null, ...args);
return (...rest) => {
let positon = 0
args = args.map(item => {
return item === _ ? rest[positon++] : item
})
return self._curry(...args, ...rest.slice(positon))
}
}
fn2 = function (x, y, z, i) { return [].slice.call(arguments).reduce((tol, cur) => tol + cur) }
Array.prototype._compose = function compose() {
let funcs = this
if (funcs.length === 0) {
return arg => arg
}
if (funcs.length === 1) {
return funcs[0]
}
return funcs.reduce((tol, cur) => {
return (...args) => tol(cur(...args));
})
}
let dispatch = action=>{
console.info(action);
return action
}
fn1 = next => action =>{
console.info('f-start');
action += 1
next(action);
console.info('f-end');
}
fn2 = next => action =>{
console.info('f2-start');
action += 1
next(action);
console.info('f2-end');
}
[fn1,fn2]._compose()(dispatch)(0)
Object.defineProperty(Array.prototype, '_flat', {
value: function () {
return this.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? cur._flat() : cur);
}, []);
}
})
function throttle(fn, wait) {
var timer;
return function (...args) {
if (!timer) {
timer = setTimeout(() => timer = null, wait);
return fn.apply(this, args)
}
}
}
fn = function () { console.log("btn clicked") }
fn1 = throttle(fn, 100);
fn1();
fn1();
setTimeout(() => fn1(), 200)