博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
惰性求值,面向对象
阅读量:3889 次
发布时间:2019-05-23

本文共 3083 字,大约阅读时间需要 10 分钟。

个人理解,所谓惰性求值,就是将所有的方法用数组存储起来,遇到一个开始计算的标志时,再遍历数组,执行方法。

1.第一种方式:面向对象的方法

// 惰性求值  const _lazy = (function () {
const MAX_ARRAY_LENGTH = 100; const LAZY_FILTER_FLAG = 1; const LAZY_MAP_FLAG = 2; LazyWrapper.prototype.filter = filter; LazyWrapper.prototype.take = take; LazyWrapper.prototype.value = lazyValue; LazyWrapper.prototype.map = map; function LazyWrapper(value) {
this.__wrapped__ = value; // 存储数据 this.__iteratees__ = []; // 存储方法,便于后期迭代操作 this.__takeCount__ = MAX_ARRAY_LENGTH; } function lazy(value) {
return new LazyWrapper(value); } function filter(iteratee) {
this.__iteratees__.push({
'iteratee': iteratee, 'type': LAZY_FILTER_FLAG }); return this; } function map(iteratee) {
this.__iteratees__.push({
'iteratee': iteratee, 'type': LAZY_MAP_FLAG }); return this; } function take(n) {
this.__takeCount__ = n; return this; } function lazyValue() {
const takeCount = this.__takeCount__; // 需要得到的数据个数 const iteCount = this.__iteratees__; // 存储的方法个数 const handleValue = this.__wrapped__; // 待处理的数据 const result = []; // 存储符合要求的数据 let resIndex = 0; checkj: // 语句标签 for (let i = resIndex; result.length < takeCount && i < handleValue.length; i++) {
const value = handleValue[i]; for (let j = 0; j < iteCount.length; j++) {
if (iteCount[j].type === 1) {
const computed = iteCount[j].iteratee(value); // 每个方法都要调用处理 if (!computed) {
// 如果不符合要求,则继续下一个数据 continue checkj; // 退出当前循环 } } } result[resIndex++] = value; } for (let j = 0; j < result.length; j++) {
const value = result[j]; for (let k = 0; k < iteCount.length; k++) {
if (iteCount[k].type === 2) {
result[j] = iteCount[k].iteratee(value); } } } return result; } return lazy; })();

总结:

  • 用立即执行函数,封装性更好,不污染全局作用域,同时,外界无法访问其内部方法。
  • 利用了原型模式和构造函数模式。

2.第二种:es6的代理Proxy

实现函数名的链式使用

const pipe = (function () {
return function (value) {
const funcStack = []; const oproxy = new Proxy({
}, {
/** * * @param pipeObject 目标对象 * @param fnName 属性名 */ get : function (pipeObject ,fnName) {
if (fnName === 'get') {
/** * val 为累加器 */ return funcStack.reduce((val, fn) => {
return fn(val); }, value); } funcStack.push(window[fnName]); return oproxy; } }); return oproxy; } }()); // 这里必须是var声明的变量,因为变量是可以挂载在window对象上的。 // 用es6的let和const,window[fnName]为undefined var double = n => n * 2; var pow = n => n * n; var reverseInt = n => n.toString().split("").reverse().join("") | 0; console.log(pipe(3).double.pow.reverseInt.get);

总结:

转载地址:http://kgthn.baihongyu.com/

你可能感兴趣的文章
C语言实现简单的分级别写日志程序
查看>>
深入理解HTTP Session
查看>>
理解TCP中的三次握手
查看>>
linux session 浅谈
查看>>
Session
查看>>
Emacs 中文学习手册-1
查看>>
Emacs学习笔记(1):初学者的学习计划
查看>>
Emacs学习笔记(13):在Emacs中打开pdf
查看>>
Emacs学习笔记(14):在Emacs中使用git
查看>>
Emacs for vim Users---from http://www.crazyshell.org/blog/
查看>>
静态库和动态库链接那些事--http://www.crazyshell.org/blog/?p=50
查看>>
使用samba实现linux,windows间文件共享
查看>>
多线程调试必杀技 - GDB的non-stop模式
查看>>
一年成为Emacs高手(像神一样使用编辑器) .--http://blog.csdn.net/redguardtoo/article/details/7222501
查看>>
GNU make 指南
查看>>
配置 vim
查看>>
CentOS6.3 minimal SSH中文显示
查看>>
centos 安装emacs24
查看>>
【转】结构体中Char a[0]用法——柔性数组
查看>>
结构体最后定义一个char p[0];这样的成员有何意义(转)
查看>>