Javascript 知识扫盲(三)

      本文仅记录一些必知的知识理论概念,用以在模棱两可的时候快速回忆相关内容。希望随着知识的应用熟练度提升,尽快将所有必知知识融入到常识之中。废话不多说,详细内容如下:

一、函数

1.1 什么是函数?

在JavaScript中,函数是基础语法之一,作用域、变量对象、闭包、this等知识点都是围绕着函数展开的。从代码上看,被 function关键词所声明的称之为函数;从实际应用上看,常见的函数形式有函数声明、函数表达式、匿名函数和自执行函数。

1.2 函数声明

	fn(); // 函数声明
	function fn() {
		console.log('函数声明');
	}

在变量对象创建的过程中,function声明的函数比var声明的变量更优先执行。因此在同一执行上下文中,无论什么位置声明了函数,都可以直接使用。

1.3 函数表达式

函数表达式指的是将函数体赋值给一个变量。

	fn(); // TypeError: fn is not function
	var fn = function() {
		console.log('函数表达式');
	}

执行过程可以参考变量,先变量提升为undefined然后再执行过程中赋值。在使用函数表达式时要注意执行顺序问题,这是与函数声明所不同的地方。

1.4 匿名函数

匿名函数一般作为一个参数或者返回值来使用,他没有名字,不易被控制台调试捕获到。

	/* 匿名函数作为参数使用 */
	var timer = setTimeout(function(){
		console.log('匿名函数');
	},1000)

	/* 匿名函数作为返回值使用 */
	function fn(message) {
		var name = 'coco';
		return function() {
			return name + ' ' + message
		}
	}
	fn('ball')();

1.5 函数自执行

自执行函数会产生独立的作用域,因此自执行函数常常用来模仿块级作用域,并进一步在此基础上实现模块化的应用。自执行函数也是匿名函数常见的执行场景之一。

在实际应用中,我们进一步通过自执行实现模块化的运用。

	(function(){
		// 私有变量
		var name = 'coco';
		var message = 'frist at all';
		var flag = false;

		// 私有方法
		function getName() {
			return `hello ` + name;
		}

		// 公有方法
		function getMessage() {
			return flag ? 'sorry I can not' : message
		}
		window.getMessage = getMessage;
	})();

当我们使用自执行创建一个模块时,就意味着,外界已经无法访问该模块内部的任何属性和方法了。我们又通过闭包技术,搭起了模块之间能相互交流的桥梁,让模块能够在我们的控制之下,选择性的对外开放属性和方法。


二、函数式编程

2.1 函数是一等公民

函数在javascript中是一等公民,函数可以作为函数参数,可以作为函数返回值,也可以赋值给变量。

例如: 字符串是在大多数语言中都是一等公民,字符串可以做为函数参数,字符串可以作为函数返回值,字符串也可以赋值给变量。

2.2 声明式编程、命令式编程、函数式编程

  • 声明式编程:专注于”做什么”而不是”如何去做”。在更高层面写代码,更关心的是目标,而不是底层算法实现的过程。如:css, 正则表达式,sql 语句,html, xml…

  • 命令式编程(过程式编程) : 专注于”如何去做”,这样不管”做什么”,都会按照你的命令去做。解决某一问题的具体算法实现。

  • 函数式编程:把运算过程尽量写成一系列嵌套的函数调用,这种函数封装思维叫做编程式思维。相比于命令式编程关心解决问题的步骤,函数式编程是面向数学的抽象,关心数据(代数结构)之间的映射关系。函数式编程将计算描述为一种表达式求值。在狭义上,函数式编程意味着没有可变变量,赋值,循环和其他的命令式控制结构。

2.3 纯函数

纯函数是一种函数特殊的函数,即相同的输入永远会得到相同的输出,而且没有任何可观察的副作用。即:不依赖外部状态,不改变外部状态,外部状态指的就是耦合度。

	function fn(num) {
		if(parseFloat(num) <= 0) return 'request error'
		return num * 1.5 + 2300;
	}

2.4 高阶函数

高阶函数其实是一个封装公共逻辑的过程。在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:

  • 接受一个或多个函数作为输入
  • 输出一个函数
	var arr1 = [1, 2, 3, 4];
	var arr2 = arr1.map(num => num * 2);

	console.log(arr1); // [1, 2, 3, 4]
	console.log(arr2); // [2, 4, 6, 8]

很多函数式编程语言都支持这个方法 map 表达式将 func 函数作用于 array 的每一个元素,并返回一个新的 array。

函数式语言通常提供非常强大的集合类(Collection),提供很多高阶函数,因此使用非常方便。

2.5 偏函数

偏函数,也叫部分应用函数,就是固化函数的一个或一些参数,只传入函数的部分参数,从而产生一个新的函数。

换言之,偏函数就是固定一个函数的一个或者多个参数,返回一个新的函数,这个函数用于接受剩余的参数。

    function add(a + b) {
         return a + b;
    }
    var add2 = add.bind(number, 5);
    
    console.log(add(2, 5));  // 2 + 5 = 7
    console.log(add2(7));  // 5 + 7 = 12

创建一个新函数,具有相同的函数体,调用时的参数被提供给模拟函数

2.6 函数柯里化

函数柯里化的概念很简单:把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数。

此外,柯里化函数有内置的迭代器机制:柯里化函数每次应用一个参数,不会做超出一个参数外的工作。调用返回的函数也就是告诉函数来进行下一步处理。

    //柯里化前
    function add(a, b, c) { return a + b + c;}
    //柯里化后
    function _add(a) { 
        return function(b) { 
            return function(c) { 
                return a + b + c; 
            } 
        }
    }
console.log(add(1)(2)(3)) // 6

柯里化的作用:不断的柯里化,累积传入的参数,最后执行,当在多次调用同一个函数,并且传递的参数绝大多数是相同的,那么该函数就可以使用柯里化。

    /* 柯里化前 */
    function userLogin1(transNo, data, func) {
        axiosPost(testUrl, {
             transNo: transNo,
             param: data
        }, func,function(error) {
             console.log(error);
        })
    }

    /* 柯里化后 */
    function userLogin2(tranNo) {
        if(!tranNo) return alert('未指定交易号');
        return function(data) {
             let request = {
                 transNo: transNo,
                 param: data
             }
             return function(func) {
                  axiosPost(testUrl, request, func, function(error) {
                      console.log(error);
                  })
             }
        }
    }

    userLogin1('T200000050', {
    	/* 参数体 */
     }, function(response) {
      	/* 方法体 */
     });
     
    userLogin2('T200000050')({ /* 参数体 */ })(function(response) { /* 方法体 */ });

函数可以作为参数传递,函数能够作为函数的返回值。

我们平时接触的函数大多都是偏函数,经过柯里化概念认知后:柯里化函数每次应用一个参数,不会做超出一个参数外的工作。调用返回的函数也就是告诉函数来进行下一步处理。


总结 : 本篇内容简单梳理了函数和函数式编程部分知识,函数式编程部分内容大都是停留在概念一级,概念扫盲不能透彻的理解一些事情,但是千里之行始于足下,我认可知识体系是不断丰富建设的,对于熟练应用掌握的那一天当是水到渠成。下一篇扫盲面向对象相关知识,其中包括构造函数与原型,原型链和经典的jQuery封装拆解。

上一篇文章: Javascript 知识扫盲(二)

下一篇文章: 预留,本店打烊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值