函数的性质,二〇一四年5个最流行前端框架相比

时间:2019-10-08 12:00来源:美高梅游戏网站
战胜 JavaScript 面试:什么是函数组合 2017/01/30 · JavaScript· 2 评论 ·函数 原版的书文出处: EricElliott   译文出处:众成翻译    Google 数据宗旨管道 — Jorge Jorquera — (CC-BY-NC-ND-

战胜 JavaScript 面试:什么是函数组合

2017/01/30 · JavaScript · 2 评论 · 函数

原版的书文出处: Eric Elliott   译文出处:众成翻译   

美高梅游戏 1

Google 数据宗旨管道 — Jorge Jorquera — (CC-BY-NC-ND-2.0)

“克制 JavaScript 面试”是自家写的一名目许多小说,来扶持面试者图谋他们在面试 JavaScript 中、高职上校恐怕会越过的片段主题素材。这几个主题素材本人本身在面试中也是有的时候会问。

函数式编程正在接管 JavaScript 世界。就在几年前,只有个别 JavaScript 程序猿知道函数式编制程序是什么。但是,在过去 3 年内,笔者所观望的每一种大型应用程序代码库都大方用到了函数式编制程序理念。

函数组合正是构成两到四个函数来生成多少个新函数的经过。将函数组合在一同,就像是将一类别管道扣合在一同,让多少流过同样。

轻易易行,函数 fg 的结缘能够被定义为 f(g(x)),从内到外(从右到左)求值。也正是说,求值顺序是:

  1. x
  2. g
  3. f

上边我们在代码中更远距离阅览一下以此概念。如果你想把客户的真名转变为 U瑞虎L Slug,给各种客商二个个人消息页面。为了促成此供给,你需求经验一种类的步骤:

  1. 将人名依照空格分拆(split)到一个数组中
  2. 将姓名映射(map)为题写
  3. 用破折号连接(join)
  4. 编码 URI 组件

日常来讲是二个简约的落到实处:

JavaScript

const toSlug = input => encodeURIComponent( input.split(' ') .map(str => str.toLowerCase()) .join('-') );

1
2
3
4
5
const toSlug = input => encodeURIComponent(
  input.split(' ')
    .map(str => str.toLowerCase())
    .join('-')
);

还不赖…不过只要本人告诉你可读性还是能更加强一些会什么啊?

若是逐个操作都有五个对应的可整合的函数。上述代码就能够被写为:

JavaScript

const toSlug = input => encodeURIComponent( join('-')( map(toLowerCase)( split(' ')( input ) ) ) ); console.log(toSlug('JS Cheerleader')); // 'js-cheerleader'

1
2
3
4
5
6
7
8
9
10
11
const toSlug = input => encodeURIComponent(
  join('-')(
    map(toLowerCase)(
      split(' ')(
        input
      )
    )
  )
);
 
console.log(toSlug('JS Cheerleader')); // 'js-cheerleader'

那看起来比大家的第三遍尝试更难读懂,但是先忍一下,大家将要化解。

为了贯彻上述代码,我们将结合两种常用的工具,举个例子 split()join()map()。如下是兑现:

JavaScript

const curry = fn => (...args) => fn.bind(null, ...args); const map = curry((fn, arr) => arr.map(fn)); const join = curry((str, arr) => arr.join(str)); const toLowerCase = str => str.toLowerCase(); const split = curry((splitOn, str) => str.split(splitOn));

1
2
3
4
5
6
7
8
9
const curry = fn => (...args) => fn.bind(null, ...args);
 
const map = curry((fn, arr) => arr.map(fn));
 
const join = curry((str, arr) => arr.join(str));
 
const toLowerCase = str => str.toLowerCase();
 
const split = curry((splitOn, str) => str.split(splitOn));

除了 toLowerCase() 外,全体那么些函数经产品测验的版本都得以从 Lodash/fp 中收获。能够像这么导入它们:

JavaScript

import { curry, map, join, split } from 'lodash/fp';

1
import { curry, map, join, split } from 'lodash/fp';

也得以像那样导入:

JavaScript

const curry = require('lodash/fp/curry'); const map = require('lodash/fp/map'); //...

1
2
3
const curry = require('lodash/fp/curry');
const map = require('lodash/fp/map');
//...

那边小编偷了点懒。注意这几个 curry 从本事上来讲,并不是一个真的的柯里化函数。真正的柯里化函数总会生成三个一元函数。这里的 curry 只是三个偏函数应用。请参谋“柯里化和偏函数应用之间的区分是如何?”那篇作品。可是,这里只是为着演示用途,我们就把它看做二个确实的柯里化函数好了。

再次来到大家的 toSlug() 达成,这里有一对事物确实让笔者很烦:

JavaScript

const toSlug = input => encodeURIComponent( join('-')( map(toLowerCase)( split(' ')( input ) ) ) ); console.log(toSlug('JS Cheerleader')); // 'js-cheerleader'

1
2
3
4
5
6
7
8
9
10
11
const toSlug = input => encodeURIComponent(
  join('-')(
    map(toLowerCase)(
      split(' ')(
        input
      )
    )
  )
);
 
console.log(toSlug('JS Cheerleader')); // 'js-cheerleader'

对自己来讲,这里的嵌套太多了,读起来有一些令人摸不着头脑。我们得以用二个会自行组合那一个函数的函数来扁平化嵌套,就是说,这些函数会从一个函数得到输出,并自行将它传递给下二个函数作为输入,直到获得终极值截止。

细想一下,好像数组中有二个函数能够做大约的作业。这一个函数便是 reduce(),它用一种类值为参数,对每个值应用五个函数,最终累加成四个结果。值笔者也得以函数。可是 reduce() 是从左到右递减,为了合作下边的结合行为,大家须求它从右到左缩减。

好专门的学业是刚刚数组也可能有三个 reduceRight() 方法能够干这件事:

JavaScript

const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);

1
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);

.reduce() 一样,数组的 .reduceRight() 方法包括三个 reducer 函数和三个起头值(x)为参数。大家得以用它从右到左迭代数组,将函数依次使用到每种数组成分上,最后获得累加值(v)。

compose,大家就足以不须要嵌套来重写上边的组成:

JavaScript

const toSlug = compose( encodeURIComponent, join('-'), map(toLowerCase), split(' ') ); console.log(toSlug('JS Cheerleader')); // 'js-cheerleader'

1
2
3
4
5
6
7
8
const toSlug = compose(
  encodeURIComponent,
  join('-'),
  map(toLowerCase),
  split(' ')
);
 
console.log(toSlug('JS Cheerleader')); // 'js-cheerleader'

本来,lodash/fp 也提供了 compose()

JavaScript

import { compose } from 'lodash/fp';

1
import { compose } from 'lodash/fp';

或者:

JavaScript

const compose = require('lodash/fp/compose');

1
const compose = require('lodash/fp/compose');

当以数学格局的结缘从内到外的角度来切磋时,compose 是确实无疑的。不过,假使想以从左到右的依次的角度来考虑,又该咋做吧?

再有别的一种样式,平时称得上 pipe()。Lodash 称之为 flow():

JavaScript

const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x); const fn1 = s => s.toLowerCase(); const fn2 = s => s.split('').reverse().join(''); const fn3 = s => s + '!' const newFunc = pipe(fn1, fn2, fn3); const result = newFunc('Time'); // emit!

1
2
3
4
5
6
7
8
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
 
const fn1 = s => s.toLowerCase();
const fn2 = s => s.split('').reverse().join('');
const fn3 = s => s + '!'
 
const newFunc = pipe(fn1, fn2, fn3);
const result = newFunc('Time'); // emit!

可以看来,那些实现与 compose() 大概统统等同。唯一的不相同之处是,这里是用 .reduce(),而不是 .reduceRight(),就是从左到右缩减,并不是从右到左。

上边大家来拜望用 pipe() 实现的 toSlug() 函数:

JavaScript

const toSlug = pipe( split(' '), map(toLowerCase), join('-'), encodeURIComponent ); console.log(toSlug('JS Cheerleader')); // 'js-cheerleader'

1
2
3
4
5
6
7
8
const toSlug = pipe(
  split(' '),
  map(toLowerCase),
  join('-'),
  encodeURIComponent
);
 
console.log(toSlug('JS Cheerleader')); // 'js-cheerleader'

对此本人来讲,那要更易于读懂一些。

骨灰级的函数式技术员用函数组合定义他们的整整应用程序。而本人反复用它来祛除不时变量。留意看看 pipe() 版本的 toSlug(),你会开采部分例外之处。

在命令式编制程序中,在一部分变量上试行转变时,在转移的各种步骤中都会找到对变量的引用。而地点的 pipe() 完结是用无点的风骨写的,就是讲罢全找不到它要操作的参数。

作者有时将管道(pipe)用在像单元测验和 Redux 状态 reducer 那类事情上,用来消除中间变量。中间变量的留存只用来保存几个操作到下三个操作之间的临时值。

那玩意初阶听上去会相比稀奇,可是随着你用它演习,会意识在函数式编制程序中,你是在和十一分抽象、广义的函数打交道,而在如此的函数中,事物的称号没那么主要。名称只会难以。你会开始把变量当做是剩下的旗帜。

正是,作者觉着无点风格或然会被用过头。它大概会变得太密集,较难精通。可是只要您搞糊涂了,这里有三个小诀要…你能够运用 flow 来追踪是怎么回事:

JavaScript

const trace = curry((label, x) => { console.log(`== ${ label }: ${ x }`); return x; });

1
2
3
4
const trace = curry((label, x) => {
  console.log(`== ${ label }:  ${ x }`);
  return x;
});

正如是你用它来追踪的主意:

JavaScript

const toSlug = pipe( trace('input'), split(' '), map(toLowerCase), trace('after map'), join('-'), encodeURIComponent ); console.log(toSlug('JS Cheerleader')); // '== input: JS Cheerleader' // '== after map: js,cheerleader' // 'js-cheerleader'

1
2
3
4
5
6
7
8
9
10
11
12
13
const toSlug = pipe(
  trace('input'),
  split(' '),
  map(toLowerCase),
  trace('after map'),
  join('-'),
  encodeURIComponent
);
 
console.log(toSlug('JS Cheerleader'));
// '== input:  JS Cheerleader'
// '== after map:  js,cheerleader'
// 'js-cheerleader'

trace() 只是更通用的 tap() 的一种特殊方式,它可以让您对流过管道的各类值实施一些表现。精晓了么?管道(Pipe)?水龙头(Tap)?能够像上边那样编写 tap()

JavaScript

const tap = curry((fn, x) => { fn(x); return x; });

1
2
3
4
const tap = curry((fn, x) => {
  fn(x);
  return x;
});

现行反革命你能够看出为嘛 trace() 只是三个特种意况下的 tap() 了:

JavaScript

const trace = label => { return tap(x => console.log(`== ${ label }: ${ x }`)); };

1
2
3
const trace = label => {
  return tap(x => console.log(`== ${ label }:  ${ x }`));
};

您应当初露对函数式编制程序是什么样样子,以及偏函数应用柯里化如何与函数组合经济合营,来接济你编写可读性越来越强的次第有一些认为了。

1 赞 9 收藏 2 评论

美高梅游戏 2

缺陷 #2 – 只度量一遍

除此以外贰个普及的荒谬是只度量一遍,然后集中开支的时日,并以此得出结论。一点都不小概试行不一致的次数会得出完全两样的结果。实行时间依附于广大意素:

  • 编辑器热身的时日(举个例子,将代码编译成字节码的日子)
  • 主线程可能正劳碌其余一些大家尚无发掘到的事体
  • 您的管理器的CPU只怕正忙辛劳碌一些会拖慢浏览器速度的事情

随地创新的格局是再度实践函数,就像这么:

JavaScript

var t0 = performance.now(); for (var i = 0; i < 10; i++) {  makeHash('Peter'); } var t1 = performance.now(); console.log('Took', ((t1 - t0) / 10).toFixed(4), 'milliseconds to generate');

1
2
3
4
5
6
var t0 = performance.now();
for (var i = 0; i < 10; i++) {
 makeHash('Peter');
}
var t1 = performance.now();
console.log('Took', ((t1 - t0) / 10).toFixed(4), 'milliseconds to generate');

本条示例的在线演示如下所示:

这种措施的高危机在于我们的浏览器的JavaScript引擎可能会使用一些优化措施,那表示当大家第贰回调用函数时,假如输入时一样的,那么JavaScript引擎只怕会记住了第壹回调用的出口,然后简短的回来那么些输出。为了缓和那一个难点,你能够利用过多不如的输入字符串,而不用重新的施用一样的输入(举个例子‘Peter’)。分明,使用不一致的输入举行测量试验带来的主题素材就是我们衡量的函数会开支不一致的时日。只怕在那之中一部分输入会费用比别的输入更加长的施行时间。

关于小编:韩子迟

美高梅游戏 3

a JavaScript beginner 个人主页 · 作者的文章 · 9 ·    

美高梅游戏 4

5) HTML Slide Presentation

美高梅游戏 5

5. UIkit by YOOtheme

UIkit 是贰个轻松的框架,它轻松使用,易于定制组件。固然它不像任何竞争对手一样受招待,但它提供了长久以来的职能和品质。

美高梅游戏 6

  • 创建者:   YOOtheme
  • 发布: 2013
  • 当前版本: 2.13.1
  • 人气: 在Github上有3,800+ stars
  • 描述: “三个轻量级的和模块化的前端框架,用于快捷支付和效用庞大的web接口。”
  • 主干概念/原则:ENCOREWD, 手提式无线电话机优先.
  • 框架大小:  118 KB
  • 预处理器:  Less, Sass
  • 响应式: Yes
  • 模块化: Yes
  • 起来模板/布局: Yes
  • Logo设置: Font Awesome
  • 附加/插件: Yes
  • 特其余机件: Article, Flex, Cover, HTML Editor
  • 文档: 良好
  • 定制: 优秀的GUI定制器。
  • 浏览器帮助: Chrome, Firefox, Safari, IE9+
  • 许可证: MIT

短处1 – 意外衡量不重大的作业

在下边的亲自过问中,你能够小心到,大家在四回调用performance.now()中间只调用了makeHash()函数,然后将它的值赋给result变量。那给大家提供了函数的施行时间,而未有其余的苦恼。我们也足以依据下边包车型客车方式来衡量代码的频率:

JavaScript

var t0 = performance.now(); console.log(makeHash('Peter'));  // bad idea! var t1 = performance.now(); console.log('Took', (t1 - t0).toFixed(4), 'milliseconds');

1
2
3
4
var t0 = performance.now();
console.log(makeHash('Peter'));  // bad idea!
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds');

其一代码片段的在线演示如下所示:

唯独在这种景色下,大家将会度量调用makeHash(‘彼得’)函数费用的年华,以及将结果发送并打字与印刷到调节台上花费的年月。我们不亮堂那个操作中每种操作实际开支稍微时间, 只知道总的时间。並且,发送和打印输出的操作所花费的日子会借助于所用的浏览器,以至借助于那时候的上下文。

大概你早已圆满的开采到console.log格局是不得以推断的。可是进行四个函数同样是一无所长的,固然种种函数都不会触发I/O操作。比方:

JavaScript

var t0 = performance.now(); var name = 'Peter'; var result = makeHash(name.toLowerCase()).toString(); var t1 = performance.now(); console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);

1
2
3
4
5
var t0 = performance.now();
var name = 'Peter';
var result = makeHash(name.toLowerCase()).toString();
var t1 = performance.now();
console.log('Took', (t1 - t0).toFixed(4), 'milliseconds to generate:', result);

同样,我们不会分晓试行时间是怎么布满的。它会是赋值操作、调用toLowerCase()函数可能toString()函数吗?

Array-Like to Array

一些时候,须要将 Array-Like Objects 转为 Array 类型,使之能用数组的局部措施,贰个特别轻易残忍並且宽容性优良的章程是新建个数组,然后循环存入数据。

我们以 arguments 为例。

function fn() { // Uncaught TypeError: arguments.push is not a function // arguments.push(4); var arr = []; for (var i = 0, len = arguments.length; i < len; i++) arr[i] = arguments[i]; arr.push(4); // [1, 2, 3, 4] } fn(1, 2, 3);

1
2
3
4
5
6
7
8
9
10
11
12
function fn() {
  // Uncaught TypeError: arguments.push is not a function
  // arguments.push(4);
 
  var arr = [];
  for (var i = 0, len = arguments.length; i < len; i++)
    arr[i] = arguments[i];
 
  arr.push(4); // [1, 2, 3, 4]
}
 
fn(1, 2, 3);

然则那不是最文雅的,更文雅的解法大家一定都精晓了,use Array.prototype.slice(IE9- 会有标题)。

function fn() { var arr = Array.prototype.slice.call(arguments); arr.push(4); // arr -> [1, 2, 3, 4] } fn(1, 2, 3);

1
2
3
4
5
6
function fn() {
  var arr = Array.prototype.slice.call(arguments);
  arr.push(4); // arr -> [1, 2, 3, 4]
}
 
fn(1, 2, 3);

恐怕能够用 [] 代替 Array.prototype 节省多少个字节。

function fn() { var arr = [].slice.call(arguments); arr.push(4); // arr -> [1, 2, 3, 4] } fn(1, 2, 3);

1
2
3
4
5
6
function fn() {
  var arr = [].slice.call(arguments);
  arr.push(4); // arr -> [1, 2, 3, 4]
}
 
fn(1, 2, 3);

如果非得追求品质,用 [] 会新建个数组,质量料定比不上前者,可是出于斯特林发动机的优化,这一点距离基本得以忽略不计了(所以众多框架用的正是后面一个)。

为啥如此能够转变?大家大约询问下,首要的开始和结果是 slice 方法只须要参数有 length 属性就能够。首先,slice 方法取得的结果是二个 新的数组,通过 Array.prototype.slice.call 传入的参数(借使为 a),若无 length 属性,大概 length 属性值不是 Number 类型,或许为负,那么直接回到三个空数组,不然重回a[0]-a[length-1] 组成的数组。(具体能够看下 v8 源码 )

理当如此,ES6 提供了更方便的法子。

var str = "helloworld"; var arr = Array.from(str); // ["h", "e", "l", "l", "o", "w", "o", "r", "l", "d"]

1
2
3
var str = "helloworld";
var arr = Array.from(str);
// ["h", "e", "l", "l", "o", "w", "o", "r", "l", "d"]

小结下,假使要把 Array-Like Objects 转为 Array,首推Array.prototype.slice,然则由于 IE 下 Array.prototype.slice.call(nodes) 会抛出荒唐(because a DOM NodeList is not a JavaScript object),所以宽容的写法如下。(但还也可以有少数要注意的是,假使是 arguments 转为 Array,最佳别用 Array.prototype.slice,V8 下会比非常慢,具体可以看下 幸免予修业改和传递 arguments 给别的方法 — 影响优化 )

function nodeListToArray(nodes){ var arr, length; try { // works in every browser except IE arr = [].slice.call(nodes); return arr; } catch(err){ // slower, but works in IE arr = []; length = nodes.length; for(var i = 0; i < length; i++){ arr.push(nodes[i]); } return arr; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function nodeListToArray(nodes){
  var arr, length;
 
  try {
    // works in every browser except IE
    arr = [].slice.call(nodes);
    return arr;
  } catch(err){
    // slower, but works in IE
    arr = [];
    length = nodes.length;
 
    for(var i = 0; i < length; i++){
       arr.push(nodes[i]);
     }  
 
    return arr;
  }
}

9) Jmpress.js

美高梅游戏 7

jmpress.js同样是创造美好演说文稿的二个有效门路。它被多量的设计师运用,它不独有交付了平价的结果,何况也极度轻松使用。使用那款框架后,你会火速见到好的硕果。

1. Bootstrap

Bootstrap 在于今风行的各个框架中是真真切切的可怜。鉴于其每一天仍在巩固的宏伟名气,能够肯定,那一个优秀的工具相对不会让您失望,它也不会在你成功创设网址前就离开到别处。

美高梅游戏 8

  • 创建者: Mark Otto and Jacob Thornton.
  • 发布: 2011
  • 如今版本: 3.3.1
  • 人气: 在Github上有75,000+ stars
  • 描述: “Bootstrap是最风靡的的 HTML, CSS和 JavaScript 响应式开拓框架 ,web上支出的第贰个活动项目.”
  • 主导概念/原则: RWD 和平运动动优先
  • 框架大小: 145 KB
  • 预管理器: Less 和 Sass
  • 响应式: Yes
  • 模块化: Yes
  • 伊始模板/布局: Yes
  • Logo设置: Glyphicons Halflings set
  • 附加/插件: 没有捆绑插件,但众多第三方插件可用.
  • 非同小可的组件: Jumbotron
  • 文档: 良好
  • 定制: 基本的GUI定制器。不幸的是,你需求手动输入的颜料值,因为尚未可用的水彩采取器。
  • 浏览器支持: Firefox, Chrome, Safari, IE8+ (你需要 Respond.js for IE8)
  • 许可证: MIT

Notes on Bootstrap

  •  Bootstrap 的重要优点是它非常红。从技艺上讲,它并不一定比这一次列出来的别样框架好,但它提供的资源(小说和课程、第三方插件和扩张、大旨开辟者等等)比别的多个框架的总和还要多。简单的讲,Bootstrap无处不在。那是大伙儿接二连三采取它的最首要缘由。
  • (注意:“独特的组件”的情致是,相比较这里提到的别的框架是无比的。)

打赏帮忙小编翻译更加的多好作品,谢谢!

任选一种支付办法

美高梅游戏 9 美高梅游戏 10

1 赞 1 收藏 评论

打赏协助本身写出越多好小说,谢谢!

美高梅游戏 11

1 赞 3 收藏 评论

10款最佳JavaScript 和 HTML5演示(幻灯片)框架

2014/12/26 · HTML5, JavaScript · HTML5, Javascript, 幻灯片

本文由 伯乐在线 - cucr 翻译,黄利民 校稿。未经许可,禁绝转发!
法文出处:devzum.com。接待参加翻译组。

JavaScript 和 HTML5 框架在今世浏览器中为创制示范文稿扮演着主要的角色。他们在web页面中放到特性,提供了一种有效的点子来显示音信。日常的话,手动编写须求大量的时光和精力。并且手动真的很复杂,初学者若无运用使得的本领无法获得丰富的果实。另一方面,演示框架具有在不发出其余难点和头眼昏花就时有发生很好的行事成果的表征。他们以最大的快慢和正确性交付最棒的web开辟成果。

HTML5在现世设计师和web开辟职员中变得不行受招待。其充分的效能和无滞后的表未来相当大程度上加强贰个网址的功用和频率。你能够很轻易地由此挑选一款能够的框架来修改你的网址的分界面外观,。没有疑问,这是微软power point和keynote的二个周密的web代替品。

故此,看看那几个一流JavaScript和HTML5演示框架,并选取最棒的一款,通过这个幻灯片演示框架的辅助来彰显你的任务。

3. Semantic UI

Semantic UI 经过长此以后的不竭,致力于能够以更语义化的秘技构建网址。它利用自然语言的标准化,使代码更可读,更便于驾驭。

美高梅游戏 12

  • 创建者:函数的性质,二〇一四年5个最流行前端框架相比较【美高梅游戏】。 Jack Lukic
  • 发布:2013
  • 眼下版本:1.2.0
  • 人气: 在Github上有12,900+ stars
  • 描述: “基于自然语言有效标准的UI组件框架”
  • 主题概念/原则: 语义,标签的龃龉性、响应式
  • 框架大小: 552KB
  • 预管理器: Less
  • 响应式: Yes
  • 模块化: Yes
  • 初叶模板/布局: No
  • Logo设置: Font Awesome
  • 附加/插件: yes
  • 独特的零部件: Divider, Flag, Rail, Reveal, Step, Advertisement, Card, Feed, Item, Statistic, Dimmer, Rating, Shape.
  • 文档: 相当好。塞马ntic提供了三个很好的组织文书档案,还会有多个提供入门指南,定制和创建核心单独的网址,。
  • 定制: 未有GUI定制器,只可以手工业定制。
  • 浏览器支持:Firefox, Chrome, Safari, IE10+ (IE9 with browser prefix only), Android 4, Blackberry 10
  • 许可证: MIT

编辑:美高梅游戏网站 本文来源:函数的性质,二〇一四年5个最流行前端框架相比

关键词: