[Javascript 进阶]-function

281 阅读3分钟

摘要

一般来说,一个函数是可以通过外部代码调用的一个“子程序”(或在递归的情况下由内部函数调用)。像程序本身一样,一个函数由称为函数体的一系列语句组成。值可以传递给一个函数,函数将返回一个值。在 JavaScript 中,函数是 头等 (first-class) 对象,因为它们可以像任何其他 对象 一样具有属性和方法。它们与其他对象的区别在于函数可以被调用本文主要收录一些关于JavaScript中函数的应用技巧,希望能够帮助到大家在开发过程中提升技巧。

IIFE 立即执行函数

(function () {
  statements;
})();

在函数体外面使用括号包裹起来,然后在使用括号执行,就能够达到立即执行的效果,但是这个函数内部的东西是无法被外部访问的,除非挂载在某个已经存在的对象上。

image.png

在项目中没有使用框架写纯js的时候会使用这种方式进行变量的隔离,然后使用公用对象进行数据传递。

arguments

在函数内部可以拿到获取到的参数的数据,arguments 对象只能在函数内使用。

function A() {
  console.log(arguments)
}

A(1,2,3, [1,2,3]);
/*
{
  "0": 1,
  "1": 2,
  "2": 3,
  "3": [
    1,
    2,
    3
  ]
}
*/

arguments 是对象,类数组,需要用from对其进行转换才能够使用数组的操作。

image.png

Function.length

获取到函数括号内部的参数个数,如果有预设参数,那么获取的个数是预设参数之前的个数。

image.png

闭包

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。

那么我们可以利用闭包的特性来进行一些timer的操作:

1. 防抖

const debounce = (fn, during) => {
    const timer = null;
    return (...args) => {
        clearTimeout(timer); // 直接clear,有的话直接销毁,没有的话也没关系
        timer = setTimeout(() => { fn(...args) }, during);
    }
}

2. 节流

const throttle = (fn, during) => {
    const timer = null;
    return (...args) => {
        if (!timer) {
            timer = setTimeout(() => {
                fn(...args);
                clearTimeout(timer);
                timer = null;
            }, during);
        }
    }
}

递归

调用自身的函数我们称之为递归函数。在某种意义上说,递归近似于循环。两者都重复执行相同的代码,并且两者都需要一个终止条件(避免无限循环,或者在这种情况下更确切地说是无限递归)。

// 将这个循环改编为递归
let x = 0;
// “x < 10”是循环条件
while (x < 10) {
  // 做些什么
  x++;
}

function loop(x) {
  // “x >= 10”是退出条件(等同于“!(x < 10)”)
  if (x >= 10) {
    return;
  }
  // 做些什么
  loop(x + 1); // 递归调用
}
loop(0);

斐波那契数列

function fib(n) {
    if (n === 1 || n === 2) return n;
    return fib(n - 1) + fib(n - 2)
}

可理化

使用递归,也可以实现可理化,柯里化是一种函数的转换,它是指将一个函数从可调用的 f(a, b, c) 转换为可调用的 f(a)(b)(c)。

柯里化不会调用函数。它只是对函数进行转换。

const curry = fn => 
    curried = (...args) => 
        (...arg) => {
            // 这个函数是递归
            if (arg.length === 0) {
                return fn(...args, ...arg)
            } else {
                return curried(...args, ...arg)
            }
        }
    const sum = (...args) => {
        return args.reduce((a,b) => a+b, 0);
    }

const curriedSum = curry(sum);
console.log('curry test',curriedSum(1)(1,3)(3,3,3,3,3,3)())

// "curry test" 23

参考文献