当前位置: 首页 > news >正文

黄南北京网站建设seo排名诊断

黄南北京网站建设,seo排名诊断,谷歌chrome,站长工具搜一搜作用 unfold 可以看做与普通聚合( fold 或 reduce )反向的一种操作:fold 可以根据数据源和条件,由包含多个元素的序列产生一个结果;而 unfold 方向相反,它根据条件由源产生了更多的结果。 它有两个优点&am…

作用

unfold 可以看做与普通聚合( fold 或 reduce )反向的一种操作:fold 可以根据数据源和条件,由包含多个元素的序列产生一个结果;而 unfold 方向相反,它根据条件由源产生了更多的结果。

它有两个优点:

  • 消除了while循环语句
  • 消除了不必要的变量声明

实现

concat版本

1.0

从 homoiconic 看到的原始版本后,第一个用JavaScript实现的想法是用 concat ,因为它没有副作用,支持链式调用:


// v1.0
Object.prototype.unfold = function(incrementor) {var r = incrementor(this);return (r != null) && [r].concat( r.unfold(incrementor) ) || [];
};// 错误的版本,错误的结果
console.log( 10..unfold(function(n) { if(n!=-2) return n - 1 }) );
// => [9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2]

1.0版 concat 函数连接结果的思路是正确的,它产生了形如 [5].concat( [4].concat( [3].concat([2].concat(...)) ) ) 式的递归调用。

缺点在于需要预先计算结果,因此声明了临时变量 r;同样的原因,因为需要预先计算,它把第一个值丢弃了,这是一个错误。

下面看看解决了上述问题的2.0版。

2.0 自定义运算符


// v2.0 
var actor = function(next,act) {return next == null ? [] : act(next);
}Object.prototype.unfold = function(incrementor) {return [this].concat(actor(incrementor(this),function(next) {return next.unfold(incrementor)}))
};// 示例1:生成字母表
var val = function(c){ return c.valueOf() };
console.log( 'a'.unfold(function(c) { if(c!='f') return String.fromCharCode(c.charCodeAt(0)+1) }).map(val) );
// => ["a", "b", "c", "d", "e", "f"]
// 示例2:列举原型链
document.querySelector('p').unfold(function(obj) { if(obj!==null) return Object.getPrototypeOf(obj) })
// => [<p>​…​</p>​, HTMLParagraphElement, HTMLElement, Element, Node,Object]
// 示例3:金字塔
var pyramid = function(char,layer) {return char.unfold(function(c) { if(c.length<layer) return c+char }).join('\n')
}
console.log( pyramid('*',5) );
// =>
// *
// **
// ***
// ****
// *****

2.0版本首先创建了一个函数 actor 作为运算符,它用于识别参数的模式:当参数为 null 或 undefined时,分叉处理。

这个版本也产生了问题:
首先,由于接受了第一值,unfold 被当作原型上的方法。此时,它输出的结果都是包装类型,所以上面例子中不得不用map循环来获取可打印的值。
其次,在JavaScript扩展 Object 的原型是个危险的举动。

解决办法之一是增加参数,来自定义每个输出项:


options || (options = {})
transformed = options.map && options.map(this) || this

或者放弃原型方法,见3.0版

2.1 漂亮的无变量声明


// v2.1
Object.prototype.unfold = function(incrementor) {return [this].concat( (function(next,act) {return next == null ? [] : act(next);})(incrementor(this),function(next) {return next.unfold(incrementor)}))
};

2.1版与2.0相同,只是隐藏了运算符,是当前最漂亮的实现。

3.0 在函数间传递状态


// 3.0 强化纯净版
var unfold = function() {var actor = function(next,act) {return next == null ? [] : act(next);}var _unfold = function(obj,incrementor,idx) {return [obj].concat(actor(incrementor(obj,idx++),function(next) {return _unfold(next,incrementor,idx)}))}return function(obj,incrementor) {return _unfold(obj,incrementor,0);}
}();// 示例 repeat
var repeat = function(char,count){return unfold(char,function(c,i) { if(i<count-1) return c }).join('')
}
var range = function(from,to){return unfold(from,function(n){ if(n<to-1) return n+1; })
}
console.log( repeat('*',10) );
// => **********
console.log( range(0,10) );
// => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

3.0版 不再扩展Object对象的原型,并且通过函数来传递状态(索引)和输入输出,进行连续计算。

由于传递了索引,它能供2.0版不能完成的功能,比如 repeat 函数。

这个版本传递基本类型时,返回的结果也全部是基本类型。

unshift版本

Array原型上的unshift方法没有连缀能力,要先改造一个:


// chained unshift
Array.prototype.unshift2 = function(){this.unshift.apply(this,arguments);return this;
}

actor版


Object.prototype.unfold2 = function(incrementor) {return actor(incrementor(this),function(next) {return next.unfold2(incrementor)}).unshift2(this)
};

伪nilclass版

这是最接近 ruby 原始实现的方式


// fake NilClass
var empty = { unfold3 : function() { return [] } }
var empty_if_nil = function(v) { return v == null ? empty : v }Object.prototype.unfold3 = function(incrementor) {return empty_if_nil( incrementor(this) ).unfold3(incrementor).unshift2(this)
}

性能


# Benchmark alphabet : 'a'~'z' iter : 188 * 800## rubyuser     system      total        real
unfold unshift   0.982000   0.000000   0.982000 (  0.972056)
unfold concat    1.202000   0.000000   1.202000 (  1.210069)
unfold while     0.717000   0.000000   0.717000 (  0.709041)## js
### proto 指原型中方法 plain 指普通函数 #chrome 13
object.proto.unfold concat: 1037ms
object.proto.unfold unshift: 988ms
object.proto.unfold fakenil: 431ms
plain.unfold recursive: 111ms
plain.unfold while: 23ms#firefox 5
object.proto.unfold concat: 1235ms
object.proto.unfold unshift: 1050ms
object.proto.unfold fakenil: 700ms
plain.unfold recursive: 1261ms
plain.unfold while: 133ms#ie 8
object.proto.unfold concat 6362ms
object.proto.unfold unshift 7572ms
object.proto.unfold fakenil 4648ms
plain.unfold recursive 6549ms
plain.unfold while 1008ms

不用多说, chrome v8在动态语言里面的表现真有王者风范。

亮点有三:原型查找很消耗时间;v8下递归函数效率很高;'fake NilClass'的版本表现也很抢眼,可以看出来,减少匿名函数创建极大地提高了效率。

总结

  • 1.0 动态语言的函数是不同的。高阶函数更加威力强大,它是处理一组相似逻辑的函数,然后在运行时再接收定义了这种逻辑的函数作为参数来调用。
  • 2.0 除了上面把函数做参数外,函数还可以看做运算符——把一个功能放置到一个单独函数里面,就是设计了自己的运算符。编写程序的过程就是不断设计这样的函数,直到得到结果。
  • 3.0 连续计算:通过函数可以把状态和值传入下一个函数进行连续计算,不需要中间声明变量。
  • Duck Typing:'fake NilClass'版本体现了这一概念,获取下一个值时,只要保证返回对象能够响应 unfold 方法即可,不管它是什么。
  • 时间消耗:匿名函数创建和原型查找都有所影响。

update@2011-09-22

测试了一个调用栈(call stack)消耗的情况:https://gist.github.com/1234338,结果如下:

递归版本检测调用栈耗尽时间就需要217912ms,仅最后一次表达式展开就需要74ms。

尾递归版本计算过程是迭代的,不需要展开表达式,效率和while循环接近。

javascript没有 TCO (tail call optimization),同样存在调用栈空间耗尽的问题:

  • 当只传递一个状态变量时, chrome v8下调用栈空间接近两万,firefox下小一半;
  • 传递状态变量越多,栈空间消耗越快;
  • 闭包版消耗了些许空间,提升了些许速度。

意义重大的是,这表明直接用函数能代替while起的控制结构作用,解决问题的思考过程也是相异的。

wikipedia 上还指出两点重要信息,不经意使用的2.0版其实有个正式的名称: CPS(continuation passing style) ;迭代时栈耗尽的问题可以用名为 trampoline 的技巧解决。

转载于:https://www.cnblogs.com/ambar/archive/2011/09/14/javascript-higher-order-function-unfold.html

http://www.lbrq.cn/news/2518507.html

相关文章:

  • 手机上那个网站做农产品推广比较好百度搜索优化建议
  • 搭建网站是什么意思重庆seo排名扣费
  • 网站ui外包阿森纳英超积分
  • 上海公司名字培训seo
  • 网站服务器做缓存百度推广合作
  • 网站做收藏本站那样seo站内优化培训
  • 高端定制站开发百度品牌专区怎么收费
  • 单位网站建设维护情况报告推广计划方案
  • 静态网页怎么做网站万网域名续费
  • sns社交网站 有哪些全网营销推广平台有哪些
  • 赤峰做网站多少钱世界新闻最新消息
  • 大连网站建设 青鸟传媒百度如何做推广
  • 浙江凌宇环境建设公司网站网络推广宣传方式
  • 免费网站建设视频代发新闻稿最大平台
  • 做网站人员工资网络营销项目策划书
  • 深圳龙岗网站建设公司seo优化网
  • 网页界面设计视觉空间的三维可视化太原seo全网营销
  • 用html制作网页seo推广优化外包价格
  • seo建站技术电商seo什么意思
  • 什么网站做视频给钱网络营销环境的分析主要是
  • 做付费推广哪个网站好百度推广课程
  • 银川做网站的公司阿里云官网首页
  • 在织梦网站做静态网页舆情监测系统
  • 全国各城市疫情高峰感染高峰进度四川seo推广
  • 东莞长安网站建设百度发视频步骤
  • 网站运营及推广个人seo怎么赚钱
  • 手机网站html竞价恶意点击立案标准
  • 温州市住建委住宅建设网站百度识图搜索
  • 外贸网站推百度关键词优化软件
  • 爱写作网站fifa最新排名出炉
  • 通达OA服务器无公网IP网络,如何通过内网穿透实现外网远程办公访问OA系统
  • Flutter封装模板及最佳实践
  • 飞书 —— 多维表格 —— AI生成
  • 多模态大模型与 AI 落地:从技术原理到实践路径的深度解析
  • 命令行创建 UV 环境及本地化实战演示—— 基于《Python 多版本与开发环境治理架构设计》的最佳实践
  • 【RHCSA 问答题】第 13 章 访问 Linux 文件系统