文档章节

函数式 JavaScript 简介

snowing1990
 snowing1990
发布于 2016/03/15 17:51
字数 1463
阅读 51
收藏 3

你肯定听说过JavaScript是一个函数式语言,或者至少知道他支持函数式编程。但是究竟什么是函数式编程?对于这个问题,如果你打算比较通用的编程范式,函数式的实现跟我们平时写的JavaScript又有什么不同?


好消息是在编程范式方面JavaScript没有那么讲究,你可以混入命令式(Imperative Programming)、面向对象、原型和函数式代码等等,只要你觉得合适,都能得到一样的结果。但是坏消息也因它而起,JavaScript在同样的代码库下同时提供了众多编程风格,所以你需要根据代码的可维护性、可读性和性能选择合适的编程方式。


函数式JavaScript并不是一定要用于整个项目中来体现它的价值。学习一点函数式的方法可以在我们构建项目时提供一些参考和帮助,而不论我们喜欢哪种方式。学习一些函数式模式和技术可以帮助我们写出更整洁、优雅的JavaScript代码,不论我们是不是真的用它。


var result;

function getText() {

  var someText = prompt("Give me something to capitalize");

  capWords(someText);

  alert(result.join(" "));

};

function capWords(input) {

  var counter;

  var inputArray = input.split(" ");

  var transformed = "";

  result = [];

  for (counter = 0; counter < inputArray.length; counter++) {

    transformed = [

      inputArray[counter].charAt(0).toUpperCase(),

      inputArray[counter].substring(1)

    ].join("");

    result.push(transformed);

  }

};

document.getElementById("main_button").onclick = getText;


这一小段代码中做了很多事:定义了一个全局变量;字符串值被传来传去,并被函数修改;还夹杂着原生JavaScript的DOM方法。函数名不是很有描述力,一定程度上因为这一切都依赖于不确定存在或不存在的上下文。但是如果你碰巧在浏览器执行了这段代码,而且网页中定义了一个<button id="main_button">,你会收到可输入文本的对话框提示,会看到那串被首字母大写了的文本。


像这种命令式代码会从顶部开始执行(如果不考虑variable hoisting的情况)。但是我们仍然可以利用JavaScript的面向对象能力来提高代码的可读性和整洁度。


面向对象的JavaScript


几后,开发者开始注意到像浏览器这样的共享环境下的命令式编程的问题。一段JavaScript代码中定义的全局变量可能会破坏另一个全局变量。代码执行的顺序和效果无法预测,尤其在网络延迟和渲染时间的影响下。


后来出现了一些好办法来封装JS代码,让它能更好地跟DOM工作。比如下面这段代码是前面代码的一种改写,使用了面向对象的方法:


(function() {

  "use strict";

  var SomeText = function(text) {

    this.text = text;

  };

  SomeText.prototype.capify = function(str) {

    var firstLetter = str.charAt(0);

    var remainder = str.substring(1);

    return [firstLetter.toUpperCase(), remainder].join("");

  };

  SomeText.prototype.capifyWords = function() {

    var result = [];

    var textArray = this.text.split(" ");

    for (var counter = 0; counter &lt; textArray.length; counter++) {

      result.push(this.capify(textArray[counter]));

    }

    return result.join(" ");

  };

 

  document.getElementById("main_button").addEventListener("click", function(e) {

    var something = prompt("Give me something to capitalize");

    var newText = new SomeText(something);

    alert(newText.capifyWords());

  });

}());


在面向对象的版本中,构造函数模拟了一个类供我们设计我们想要的对象,方法定义在对象的原型中来降低内存使用。所有的代码都封闭在一个匿名的及时调用函数表达式中,所以它不会污染全局作用域。”use strict”强制使用最新的JavaScript引擎,onclick方法被新引入的addEventListner代替,毕竟没人再使用比IE8还古董的浏览器了。这段代码可以被插入在<body>段的最后,使得所有的DOM加载完成后才执行,这时候<button>才可用。


函数式JavaScript


相比我们开始说的命令式代码,面向对象确实能使代码更整洁、模块化更好,但我们看能否通过解决它的一些缺点来使它更完美。如果我们能通过JavaScript的一些内建特性,把函数当“第一类对象”看待,我们的代码会更加干净、稳定、易拓展。


(function() {

  "use strict";

  var capify = function(str) {

    return [str.charAt(0).toUpperCase(), str.substring(1)].join("");

  };

  var processWords = function(fn, str) {

    return str.split(" ").map(fn).join(" ");

  };

  document.getElementById("main_button").addEventListener("click", function(e) {

    var something = prompt("Give me something to capitalize");

    alert(processWords(capify, something));

  });

}());


发现这个版本短了多少没?我们制定一了capify和processWords两个函数,每个函数都是pure的,也就是说他们不依赖于调用他们的代码的状态。函数不会改变他们之外的变量。针对给定的任意参数,返回唯一的结果。由于这些改进,新的函数易于测试,也很容易被移植。


刚才那段代码中可能有个函数你没见过,我们在Array上使用map方法,可以对Array上每个元素应用fn函数(fn是传入的参数)。运行在现代浏览器和服务端的实现了ES5的JavaScript为我们提供了这个方便的函数。这里不需要使用for循环,只使用一个map,可以避免使用循环变量,提高代码的整洁度和可读性。


对函数式的思考


你用为了函数范式而抛弃使用的一切,而是在你做下一个项目的时候,可以用函数的思维来考虑一下下面的问题:


  • 我的函数依赖调用上下文吗?他们是独立的吗?

  • 我可以把函数写成对某个输入总有相同返回值的吗?

  • 我的函数不改变函数外的变量吗?

  • 如果我想要在其他项目中使用这个函数,我需要修改他们吗?


这篇介绍仅仅是揭露了函数式JavaScript的表面,但希望它能引起你的探究欲望而学到更多。


本文转载自:http://web.jobbole.com/85266/

snowing1990
粉丝 4
博文 90
码字总数 2952
作品 0
程序员
私信 提问
(译) 函数式 JS #1:简介

“written equations on brown wooden board” byRoman Mager onUnsplash 原文链接 By: Krzysztof Czernek 简介 如果你是一名 JavaScript 开发人员,那么你很可能会 已经看到过"函数式编程"......

RockyDd
01/11
0
0
每个JavaScript工程师都应懂的33个概念

摘要: 基础很重要啊! 原文:33 concepts every JavaScript developer should know 译文:每个 JavaScript 工程师都应懂的33个概念 作者:stephentian Fundebug经授权转载,版权归原作者所有...

Fundebug
2018/10/30
0
0
JavaScript开发者应懂的33个概念

简介 这个项目是为了帮助开发者掌握 JavaScript 概念而创立的。它不是必备,但在未来学习(JavaScript)中,可以作为一篇指南。 本篇文章是参照 @leonardomso 创立,英文版项目地址在这里。 ...

大灰狼的小绵羊哥哥
2018/10/22
0
0
Web前端 — Bootstrap(1)

Bootstrap本次知识点: 1.Bootstrap简介 2.什么是Bootstrap 3.为什么使用Bootstrap 4.Bootstrap的结构 5.BootStrap的基本模板 1.Bootstrap简介 Bootstrap,来自Twitter(全国最大的微博 )的两...

凤囚凰丶
2018/06/01
0
0
《JavaScript 权威指南》读书笔记 1 - 简介

原文:https://keelii.github.io/2016/06/16/javascript-definitive-guide-note-0/ 第一章 主要介绍 JavaScript 的大概情况、基本语法。之前没有 JavaScript 基础的看不懂也没关系,后续章节...

keelii
2016/06/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

从零基础到拿到网易Java实习offer,我做对了哪些事

作为一个非科班小白,我在读研期间基本是自学Java,从一开始几乎零基础,只有一点点数据结构和Java方面的基础,到最终获得网易游戏的Java实习offer,我大概用了半年左右的时间。本文将会讲到...

Java技术江湖
昨天
5
0
程序性能checklist

程序性能checklist

Moks角木
昨天
7
0
VUE 计算属性

本文转载于:专业的前端网站▶VUE 计算属性 1、示例代码 <!DOCTYPE html><html lang="zh"> <head> <meta charset="UTF-8" /> <title>vue示例</title> </hea......

前端老手
昨天
6
0
快速搭建LNMT平台和环境部署 Tomcat详解

Tomcat部署的基本概念 1. CATALINA_HOME与CATALINA_BASE分别指什么?     CATALINA_HOME指的是Tomcat的安装目录     bin:\\Tomcat一些脚本存放目录,比如启动脚本startup.bat/start...

网络小虾米
昨天
7
0
float浮动

float浮动 float浮动概念及原理: 文档流:文档流是文档中可显示对象在排列时所占用的位置。 加浮动的元素,会脱离文档流,会沿父容器靠左或靠右排列,如果之前已经有浮动的元素,会挨着浮动...

studywin
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部