JavaScript探索:从两数之和学习伪数组、参数校验和记忆函数

如果让你写一个求两数之和的函数,你能确保你的函数能够没有一点破绽吗?今天我们将从两数之和开始,带你学习js中的伪数组、参数校验和记忆函数。

两数之和

现在让你写一个两数之和的函数,你可能会想,这有什么难的,那你的函数是不是和这样的差不多呢?

css 复制代码
function add(a,b){
    return a+b
}

看起来没什么问题对吧,但真的有那么简单吗?

如果我传三个数进去add(1,2,3),你要如何应对呢?

如果我传字符串进去add(1,i),你又该如何应对呢?

所以看起来没问题,但实际上问题很大。接下来一起看看这些问题要怎么解决吧!

伪数组arguments

在JavaScript中,arguments是一个特殊的对象,它包含了函数调用时传递的所有参数。它可以在函数内部使用,用于访问和操作传递给函数的参数。

arguments对象类似于一个数组,但它并不是一个真正的数组,而是一个类似数组的对象。它具有length属性来表示传递给函数的参数个数,并且可以通过索引访问每个参数的值。

以下是arguments对象的一些常见用法示例:

访问参数值:

javascript 复制代码
function myFunction(a, b) {
  console.log(arguments[0]); // 输出第一个参数的值
  console.log(arguments[1]); // 输出第二个参数的值
}
myFunction('Hello', 'World');
// 输出:
// Hello
// World

遍历参数:

javascript 复制代码
function myFunction() {
  for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}
myFunction('Hello', 'World');
// 输出:
// Hello
// World

在两数之和问题中,如果我们要限定传进来的参数个数,可以借助arguments来实现:

javascript 复制代码
function add(a,b){
    if(arguments.length!=2){
        throw new Error('必须传递两个参数')//抛出错误,程序终止
    }
    return a+b
}

console.log(add(1,2,3));

参数传进来后,我们先用arguments.length来判断参数的数量是否是2,如果不是则抛出错误,这里我们使用throw new Error(),程序会立即终止。

如果你想要程序还能继续运行,可以用try{}catch(e){console.log(e);}:

javascript 复制代码
function add(a,b){
    if(arguments.length!=2){
        throw new Error('必须传递两个参数')
    }
    return a+b
}
try{   // 抛出错误,还能继续执行
    console.log(add(1,2,3));
}catch(e) {
    console.log(e);
}
console.log('continue...')

抛出错误后,还能继续执行之后的console.log('continue...')

使用arguments需要注意的是,arguments是一个伪数组,它没有数组的一些方法,如push()或pop(),也不能使用join()。如果需要使用数组的方法,可以将arguments对象转换为真正的数组 ,例如使用Array.from(arguments)[...arguments]

参数校验

解决了参数数量问题,我们再来看如何解决参数的数据类型问题。

在JavaScript中参数校验是指对函数或方法的输入参数进行验证和检查的过程。它旨在确保传递给函数的参数满足预期的条件和要求,从而提高代码的可靠性和安全性。

这里我们进行数据类型验证:检查参数的数据类型是否符合预期,如数字、字符串、数组等。

要得到参数的数据类型是什么,我们可以使用typeof

javascript 复制代码
if(typeof a !== 'number' || typeof b !== 'number'){
    throw new Error('必须是整数');
}

如果两个参数中部全是整数,则抛出错误。

现在,这个函数就已经变得很完美啦!

javascript 复制代码
function add(a,b) {
    if(arguments.length !== 2){
        throw new Error('传递的参数个数有误');
    }
    if(typeof a !== 'number' || typeof b !== 'number'){
        throw new Error('必须是整数');
    }
    return a+b
}

记忆函数

上面的add函数,如果我们多次调用它,但每次传进去的参数都是相同的,那它就会重复做很多相同的运算,那么有没有办法能够减少它的重复运算,提高效率,让它更完美呢?当当~这个时候就轮到记忆函数出场了!

在JavaScript中,记忆函数(Memoization Function)是一种优化技术,用于缓存函数的计算结果,以避免重复计算相同的输入值。记忆函数可以显著提高函数的性能,尤其是对于那些计算量较大、耗时较长的函数。

记忆函数的核心思想是将函数的输入值与其对应的输出结果保存在一个缓存对象中。当函数被调用时,首先检查缓存中是否已经有了该输入值的计算结果,如果有,则直接返回缓存中的结果,而不需要重新执行函数体。如果缓存中没有对应的结果,则执行函数体计算结果,并将计算结果存入缓存中供下次使用。

javascript 复制代码
function add(a,b) {
    if(arguments.length !== 2){
        throw new Error('传递的参数有误');
    }
    if(typeof a !== 'number' || typeof b !== 'number'){
        throw new Error('必须是整数');
    }
    return a+b
}
// 记忆函数 
function memorize(f){
    if(typeof f !== 'function') return;
    var cache = {} //缓存空间
    return function(){
        var key = arguments.length + Array.prototype.join.call(arguments,',')
        if(key in cache){  // 如果缓存中已有结果,则直接返回
            return cache[key]
        }else{
             // 执行函数体计算结果
            return cache[key] = f.apply(this,arguments)
        }
    }
}

const memorizedAdd = memorize(add);
console.log(memorizedAdd(1,2));//通过add计算出值
console.log(memorizedAdd(1,2));//从cache中取值不用再调用add计算

第一遍计算的输入值与输出结果会保存在cache中,如果之后有相同的输入则直接取值不用再计算了,若没有则进行计算并存入cache中。

这次的知识点已经讲完啦!欢迎下次再来一起学习哦ヾ(◍°∇°◍)ノ゙

相关推荐
SameX1 分钟前
初识 HarmonyOS Next 的分布式管理:设备发现与认证
前端·harmonyos
M_emory_28 分钟前
解决 git clone 出现:Failed to connect to 127.0.0.1 port 1080: Connection refused 错误
前端·vue.js·git
Ciito31 分钟前
vue项目使用eslint+prettier管理项目格式化
前端·javascript·vue.js
成都被卷死的程序员1 小时前
响应式网页设计--html
前端·html
fighting ~1 小时前
react17安装html-react-parser运行报错记录
javascript·react.js·html
老码沉思录1 小时前
React Native 全栈开发实战班 - 列表与滚动视图
javascript·react native·react.js
abments1 小时前
JavaScript逆向爬虫教程-------基础篇之常用的编码与加密介绍(python和js实现)
javascript·爬虫·python
mon_star°1 小时前
将答题成绩排行榜数据通过前端生成excel的方式实现导出下载功能
前端·excel
Zrf21913184551 小时前
前端笔试中oj算法题的解法模版
前端·readline·oj算法
老码沉思录2 小时前
React Native 全栈开发实战班 - 状态管理入门(Context API)
javascript·react native·react.js