JS函数详解

JS函数详解

Posted by limantang on November 12, 2019

JS函数全解

函数是什么

对于汇编语言来说函数其实就是汇编语言当中的子程序, 子程序有几个特点

  • 由一条或者多条语句组成
  • 功能相对独立
  • 完成特定的任务

子程序又衍生了以下三种

  1. 有返回值的叫做函数
  2. 没有返回值的叫做过程
  3. 存在于类中或者对象中的叫做方法 对于JS来说只有函数方法, 因为JS所有的函数都有返回值, 默认是undefined

数学领域中也有函数, 数学领域函数的特点

  • 函数在数学领域中是两个非空集合的一种对应关系
  • 定义域中的每一项元素皆对应值域中的一项元素

如何理解?

  • 假设函数为f
  • 假设输入为x1, 那么必然有一个输出y1: f(x1) = y1
  • 假设输入为x2, 那么对应的输出可以是y1,也可以不是y1
  • 但是不论输入多少次x1, 不论什么时间输入x1, 输出永远是确定的y1

函数式编程

如果你编写的编程语言中的函数符合数学定义中函数, 那么你的函数就是函数式(函数式里面的函数二字含义是数学中的函数)

编程语言中的函数

今天不讨论函数式, 只讨论编程语言中的函数

函数的返回值由什么决定呢?

  • 函数调用时输入的参数params
  • 定义时的环境env

举个例子

    let x = 'x';
    let a = 1;
    function f1(x) {
        return x + a;
    };
    {
        let a = '2';
        f1('x')
    }

这个函数执行最终返回的结果是’x1’, 而不是’x2’, 有的同学可能误以为返回’x2’ 对于上面代码的理解, 参数x就是函数调用时才输入的, 而变量a是函数定义时就确定的使用的变量, 也就是说变量a就是环境, 一定要明确定义时, 函数调用时这两个时间点, 以及参数值得确定是函数调用时, 环境的确定是函数定义时

并不是所有的编程语言都支持函数访问外层的变量

在JS中大家习惯了函数访问函数本身以外的外层变量, 但是并不是所有的编程语言都支持这种做法, 例如Ruby, 感兴趣的可以去了解一下, 但是Ruby通过lambda也实现了这种做法

闭包

如果函数在函数里面可以访问外面的变量, 那么这个函数 + 这些变量 = 闭包 闭包 + 时间就是一些经典的面试题, 要考虑时间的因素 , 刻舟求剑的故事

闭包的特点

  • 闭包能够让一个函数维持住一个变量
  • 但是不能维持这个变量的值
  • 尤其是这个变量的值会发生变化的时候

对象是穷人的闭包

  • 对象也可以维持住一个变量
  • 如果一门语言不支持闭包, 你可以使用对象代理

举例说明

    const obj = {
        i: 1,
        fn() {
            return this.i;
        }
    }
    
    const handle = !function(){
        const i = 1;
        return function (){
            return i;
        }
    }()

上面代码都是为了函数可以访问i这个变量

闭包是穷人的对象

如果一门语言不支持对象, 你可以使用闭包代理对象 这句话有些抽象, 举例说明一下 假设JS不支持对象

    function createPerson(age, name) {
        return function (key) {
            if (key === 'name') return name;
            if (key === 'age') return age;
        }
    }
    
    const person = createPerson(18, 'limantang');
    person('name');
    person('age');

上面代码中的person是不是很像一个对象通过属性来获取值 这就解释了闭包是穷人的对象这句话

闭包是为了维持住一个变量,通过这一点产生了很多种的用法, 例如变量私有化