形式化运算系统的研究:

  • 图灵:提出图灵机形式系统,通过0,1运算系统来解决复杂问题;
  • 冯诺依曼:提出了冯诺依曼体系;即通过修改内存反映运算结果;
  • 阿隆左.丘奇:提出新的运算范型Lambda演算,计算机运算才是本质,修改内存只不过是这种运算规则的副作用;

后出现函数式语言的鼻祖:LISP;

函数式语言

  • 通过连续表达式运算求值的语言;
  • 由于现在的计算机都是基于冯诺依曼体系建立的,所以函数式语言就是运行在解释环境而非编译环境的;

结果:大多数人都在使用基于冯诺依曼体系的命令式语言,但为了获得特别的计算能力或者编程特征,这些语言也在逻辑层实现一种适宜于函数式语言范式的环境。一方面产生了如JS这样多范式语言,另一方面产生了如.NET,JVM的能够进行某些函数式计算的虚拟机环境;

函数式语言中的函数(性质)

  • 能被调用;
  • 函数是运算元:js中将函数当参数时,传递引用但并没有地址概念,因此与普通参数并没有不同;
  • 在函数内保存数据:
    • 在命令式语言中,函数内部的私有变量是不能被保存的;因为局部变量在栈上分配,函数结束后所占用的栈会被释放;
    • 在js的函数中,函数内的私有变量可以被修改,而且当再次进入到该函数内部时,这个被修改的状态仍将持续;
    • 在函数内保持数据的特性被称为闭包;
  • 函数内的运算对函数外无副作用:(依赖开发人员的编程习惯)
    • 作为值参数而不是变量参数使用;
    • 不修改函数外部的其他数据;
    • 运算结束通过函数返回向外部系统传值;

//不修改全局变量,且不在函数内修改对象和数组成员;这些成员应该由对象方法而非对象系统外的其他函数来修改;这里可以综合考虑对象系统的接口特性;

从运算式语言到函数式语言: 

  • JS中几种连续运算:

    • 连续赋值;
    • 三元表达式(推荐连用);
    • 连续的逻辑运算;
    • 链式运算;
  • 运算式语言:因为运算都是产生值类型的结果,且所有的逻辑语句结构都可以被消灭;所以系统的结果必然是值,并且可以通过一些列的运算来得到这一结果;
  • 消灭语句:
    • 分支语句

      if(tag > 1) {
      console.log('true');
      } (tag > 1) && console.log('true');
      (tag > 1) ? console.log('true') : null;
      ---------------- if(tag > 1) {
      console.log('true');
      } else {
      console.log('false');
      } (tag > 1) ? console.log('true') : console.log('false'); ---------------- switch(value) {
      case 100:
      case 200: console.log('100~200'); break;
      case 300: console.log('300'); break;
      default: console.log('default');
      } (value == 100 || value == 200) ? console.log('100~200')
      : (value == 300) ? console.log('300')
      : console.log('default');
    • 循环语句
      var i = 100;
      
      do {
      //do something
      i--;
      }while(i > 0); /**/
      function foo(i) {
      //do something
      if( --i > 0) foo(i);
      }
      foo(i);
      /*better*/ void function(i) {
      //do something
      (--i > 0) && arguments.callee(i);
      }(i);

      //循环语句良好的特性就是开销小;函数递归中,由于需要每次函数调用保留私有数据和上下文环境,所以将消耗大量栈空间,可能造成栈溢出;尾递归(即在执行序列的最后一个表达式中出现递归调用)可以消除这种情况,但JS解释环境不支持这种特性;

 函数式语言:

  • 函数:本质上来讲,函数式语言中的函数应该是‘lambda(函数)’,而不是一般提及的function;
  • 概括JS满足函数式语言的特性:
    • 在函数外消除语句,只使用表达式和函数,通过连续求值来组织代码;
    • 在值概念上,函数可以作为运算元参与表达式运算;
    • 在逻辑概念上,函数等义于表达式运算符,其参数是运算元,返回运算结果;
    • 函数严格强调无副作用;

JS中的函数:

  • 可变参数与值传递:

    • JS特点

      • 从左至右传入参数;
      • 传入参数的引用,函数内对它的任何修改都不会被传出;
      • 传入参数的个数是可变的; //所以很多情况下需要arguments;
  • 非惰性求值; //对函数来说,如果一个参数是需要用到时才会完成求值,就是惰性求值,而JS的函数是非惰性求值
  • 函数是第一型的; //由于此特征,JS函数即可以做运算元,也可以做运算符;
  • 函数是一个值; //基于对象来讲,JS中所有东西都是对象;函数式语言来讲,所有东西都是值;
  • 可遍历的调用栈:

//一个静态未调用的函数只是一个值,当它(F)调用时,系统将正在运行的函数(A)入栈,并保留函数A的执行指针;在函数F执行完之后,函数A出栈并继续执行指针后的代码;

function F() {
}
function A() {
F(x,y,z);
}
    • callee:    //arguments.callee;

      • 总是指向arguments创建的函数;
      • 对于匿名函数和函数重写的特性的有意义;
    • caller:   //Function.caller;
      • 总是执行调用这个函数的函数;
      • 如果多个函数都调用这个函数,那么JS会无法识别并导致出错;所以ECMA标准并不提倡使用;

js:语言精髓笔记9--函数式语言特征的更多相关文章

  1. js:语言精髓笔记11--动态语言特性(1)

    语言:程序最终被表达为数据(结构)和逻辑(算法),命令式和说明式/函数式语言分别从这两方面分类: 动态:在语言陈述时无法确定,必须在计算机执行时才能确定语言关系:JS是完全动态语言,导致其不确定性一般 ...

  2. js:语言精髓笔记12--动态语言特性(2)

    对于括号内: 通过赋值时发生的重写: (Object1 = function() {}).prototype.value = 100; var obj1 = new Object1; console. ...

  3. js:语言精髓笔记7----原型继承

    面向对象有三个基本特性:封装,继承,多态:如果都满足的话称为面向对象语言:而部分满足则称为基于对象语言: 数据类型实现模型描述: JavaScript对象模型: 构造过程:函数->构造器 构造器 ...

  4. js:语言精髓笔记5----语言分类

    计算模型:源于对计算过程的不同认识: 1.基于不同计算模型一般分为://教科书的一般分类 命令式语言: 函数式语言: 逻辑式语言: 面向对象程序设计语言: 2.基于程序本质分类:  //编程的经典法则 ...

  5. Go语言学习笔记(一) [Go语言的HelloWorld]

    日期:2014年7月18日   1.简介     Go 编程语言是一个使得程序员更加有效率的开源项目.Go 是有表达力.简 洁.清晰和有效率的.它的并行机制使其很容易编写多核和网络应用,而新奇的类型系 ...

  6. C语言学习笔记一---C语言概述

    一.编程语言与解释语言 1.程序的执行 a.解释:借助一个能试图理解程序的程序,使计算机按要求执行你自己写的程序 b.编译:将所写程序翻译为机器语言写的程序,使计算机按要求执行你自己写的程序 2.两者 ...

  7. js:语言精髓笔记8--对象系统

    封装: 一把对象系统,封装是由语法解析来实现的,即语法作用域:但js是动态语言,因此只能依赖变量作用域: js的变量作用域只有表达式,函数,全局三种:所以js只能实现public和private两种封 ...

  8. js:语言精髓笔记1--标识符与基本类型

    标识符: 命名: 语法以及类型----语法关键字                                           //逻辑 值(的存储位置)----变量和常量           ...

  9. js:语言精髓笔记10--闭包

    闭包:  //JS函数式风格中,在内部保存数据和对外无副作用这两个特性主要就是通过闭包实现的: 函数与闭包: 一个函数是一段静态代码,它是一个代码书写时已经编译期,静态概念:闭包是函数在代码运行过程中 ...

随机推荐

  1. 让我们一起学习《Node.js入门》一书吧!

    Node.js入门 读完本书之后,你将完成一个完整的web应用,该应用允许用户浏览页面以及上传文件. 里面对一些知识的讲解,让你略窥Node.js的门径.最好一段代码一段代码的写下来,我的习惯是手里拿 ...

  2. matlab 之字体调整

    FontWeight {normal} | bold | light | demi

  3. 基础知识系列☞GET和POST→及相关知识

    参考资料: [1].<IT企业必读的200个.Net面试题> [2].http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.htm ...

  4. HDOJ 1907 John

    对于任意一个 Anti-SG 游戏,如果我们规定当局面中所有的单一游戏的 SG 值为 0 时,游戏结束,则先手必胜当且仅当:  (1)游戏的 SG 函数不为 0 且游戏中某个单一游戏的 SG 函数大于 ...

  5. LayoutComponent类,用于layout的组件类。 LayoutComponent保存的所有用于布局的数据。

      LayoutComponent ()   默认构造函数 更多...     ~LayoutComponent ()   默认的析构函数 更多...     CREATE_FUNC (LayoutC ...

  6. android webview删除缓存

    [1].[代码] 删除保存于手机上的缓存. 跳至 [1] [2] [3] 01 // clear the cache before time numDays     02 private int cl ...

  7. Android 下载文件及写入SD卡

    Android 下载文件及写入SD卡,实例代码 <?xml version="1.0" encoding="utf-8"?> <LinearL ...

  8. C++多态公有继承

    面向对象的三个基本特征 面向对象的三个基本特征是:封装.继承.多态.其中,封装可以隐藏实现细节,使得代码模块化:继承可以扩展已存在的代码模块(类):它们的目的都是为了——代码重用.而多态则是为了实现另 ...

  9. 3.子数组的最大和[MaximumContinuousSubArray]

    [题目]: 输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值,要求时间复杂度为O(n). 例如输入的数组为1, -2, ...

  10. 转数据库Sharding的基本思想和切分策略

    本文着重介绍sharding的基本思想和理论上的切分策略,关于更加细致的实施策略和参考事例请参考我的另一篇博文:数据库分库分表(sharding)系列(一) 拆分实施策略和示例演示 一.基本思想 Sh ...