javascript功能_功能JavaScript简介

javascript功能

本文包含在我们的选集Modern JavaScript中 。 如果您希望所有内容都集中在一个地方,以适应最新JavaScript,请注册SitePoint Premium并下载一个副本。

您已经听说JavaScript是一种功能语言,或者至少它能够支持功能编程。 但是什么是函数编程? 因此,如果您要开始比较一般的编程范例,那么功能方法与您一直编写JavaScript有何不同?

好消息是,在范式方面,JavaScript并不挑剔。 您可以按照自己的意愿混合使用命令式,面向对象,原型和功能代码,并且仍然可以完成工作。 但是坏消息对您的代码意味着什么。 JavaScript可以在同一代码库中同时支持多种编程样式,因此您需要根据可维护性,可读性和性能做出正确的选择。

功能性JavaScript不必接管整个项目即可增加价值。 稍微了解一下功能方法,可以帮助您在构建项目时做出一些决策,而无论您希望以何种方式构造代码。 学习一些功能模式和技术可以使您顺利地编写更简洁,更优雅JavaScript,而不论您采用哪种方法。

命令式JavaScript

JavaScript首先作为浏览器内语言而流行,主要用于向网页元素添加简单的悬停和单击效果。 多年来,这是人们所了解的大部分内容,这也导致了早期获得JavaScript的不良声誉。

当开发人员努力将JavaScript的灵活性与浏览器文档对象模型(DOM)的复杂性相匹配时,实际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;

这小段代码中发生了很多事情。 在全局范围内定义变量。 值被函数传递和修改。 DOM方法与本机JavaScript混合在一起。 函数名称不是很具描述性,部分原因是整个事实都依赖于可能存在或不存在的上下文。 但是,如果您碰巧在定义了<button id="main_button">HTML文档中的浏览器中运行此<button id="main_button"> ,则可能会提示您输入一些文本,然后看到带有每个文本首字母的alert该文本中的单词大写。

这样的命令性代码被编写为从上到下读取和执行(给出或采取一些可变的提升 )。 但是,我们可以通过利用JavaScript的面向对象性质来进行一些清理,以使其更易于阅读。

面向对象JavaScript

几年后,开发人员开始注意到在诸如浏览器之类的共享环境中使用命令式编码的问题。 一个JavaScript代码段中的全局变量破坏了另一个变量设置的全局变量。 调用代码的顺序以无法预测的方式影响结果,尤其是考虑到网络连接和渲染时间带来的延迟。

最终,出现了一些更好的实践来帮助封装JavaScript代码并使其在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 < 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方法已被闪亮的新addEventListener取代,因为谁在使用IE8或更早版本? 像这样的脚本可能会插入HTML文档的<body>元素的末尾,以确保在处理所有DOM之前已加载所有DOM,以便它依赖的<button>可用。

但是尽管进行了所有这些重新配置,仍然有许多具有相同命令风格的工件导致了我们的到来。 构造函数中的方法依赖于范围限定于父对象的变量。 有一个循环结构可以遍历字符串数组的所有成员。 有一个counter变量,除了通过for循环增加进度外,没有其他用途。 某些方法会产生修改其定义之外的变量的副作用。 所有这些都使代码变得更脆弱,更不便于移植,并使得在这种狭窄环境之外测试方法变得更加困难。

功能性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));
  });
}());

您是否注意到此版本短了多少? 我们仅定义两个函数: capifyprocessWords 。 这些函数中的每一个都是纯函数,这意味着它们不依赖于调用它们的代码的状态。 这些函数不会产生副作用,不会改变自身之外的变量。 对于任何给定的参数集,函数返回的结果只有一个。 由于这些改进,新功能非常易于测试,可以直接从此代码中删除,并可以在其他地方使用而无需进行任何修改。

除非您之前已经看过一些功能代码,否则可能只有一个关键字无法识别。 我们利用Array上的新map方法将函数应用于拆分字符串时创建的临时数组的每个元素。 当现代浏览器和服务器端JavaScript解释器实现ECMAscript 5标准时, Map只是我们提供的少数便利方法之一。 仅在这里使用map代替for循环,消除了counter变量,并帮助使我们的代码更加简洁和易于阅读。

开始思考功能

您不必为了使用功能范式而放弃所有已知的知识。 在编写下一个程序时,可以通过考虑一些问题来开始以功能性方式考虑JavaScript:

  • 我的函数是否取决于调用它们的上下文,或者它们是纯独立的?
  • 我可以以依赖于它们始终为给定输入返回相同结果的方式来编写这些函数吗?
  • 我确定我的函数不会在自身之外进行任何修改吗?
  • 如果我想在其他程序中使用这些功能,是否需要对其进行更改?

简介几乎没有触及功能JavaScript的表面,但是我希望它能激发您的胃口,以了解更多信息。

翻译自: https://www.sitepoint.com/introduction-functional-javascript/

javascript功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值