用“Function“替代“eval“进行动态代码生成

news2025/2/24 12:35:31

一、背景

 在JavaScript中我们有时会遇到这么一个场景:“函数可能要根据不可预知的条件执行代码”。比如说计算器中的加减乘除,用户无法直接将操作符"+、-、*、/"作为参数传入函数中,因此我们一般会采取字符串形式的操作符,但如此操作同样会存在一个问题,我们也无法使用策略模式(Map集合匹配操作符)。

 当然在这种情况下,我们可以使用switch语句来实现字符串的一一匹配。不过这种方式必然存在的问题便是,当换一个场景,用户可能输入的"条件"数量大起来之后,代码量便会不停的增加并不易于维护。

 那么我们会想,能不能用"通用性"代码来处理这个问题呢?首先我们会想到的便是处理"动态代码生成"的方法"eval"。

二、Eval 动态生成代码

 使用Eval,我们便可以使用字符串拼接的方式,使得这个不可预知条件函数的正常执行,举个栗子:

function calculate(firstOperand, operation, secondOperand) {
  return eval('firstOperand' + operation + 'secondOperand');
}

calculate(1, '+', 2); // -> result: 3
calculate(1, '>', 2); // -> result: false

 上述例子中,我们通过eval实现了一个简易计算器的功能,使之用户可以传入字符串形式的比较符,同样的,当用户传入的符号为比较运算符时,也能得到对应的结果。

 虽然说Eval能够完成我们的目标,但并不是推荐使用Eval来进行动态代码生成,因为Eval在非严格模式下存在较为严重的"副作用",副作用简单来说就是当前函数的执行会导致外界作用域的改变。副作用的问题可以通过开启严格模式来得到一定的缓解。同时Eval也存在一定的性能问题。

三、Function 构造函数

 相较于Eval,我们更推荐使用Function构造函数来创建一个函数,那它相比于Eval有哪些优势呢?首先new Function创建的函数是无法访问到当前闭包的局部变量,只能访问全局作用域,减少了副作用的影响。同时使用new Function具备更好的维护性,在使用eval中使用到外部函数的相关变量时在编辑器中我们是无法看见形参的高亮,也就无法准确判断该参数是否被使用,如下:

 在使用Function构造函数来创建则可以避免这个问题,使整体代码更易于维护,将上述的eval代码修改为Function构造函数创建的动态代码如下:

function calculate(firstOperand, operation, secondOperand) {
  const calculateFn = new Function('firstOperand', 'secondOperand', 
  	'return firstOperand' + operation + 'secondOperand;');
  return calculateFn(firstOperand, secondOperand);
}

console.log(calculate(1, '+', 3));

 当然了,你也可以将operation作为参数传入,同样的在函数体的部分你也可以通过模板字符串来完成,这可以使得代码更具可读性。

 另外提一句,使用Function构造函数的情况下,我们能够在严格模式下使用with关键字,代码示例如下:

 在eval中是无法使用的,这点大家可以自行测试。

四、总结

 总之,在需要使用到动态代码生成的时候,我们有两个方法:“eval"与"Function”,相较而言更为推荐使用Function构造函数,不止因为他在安全、可维护性上优秀于Eval,同时也是因为在有需求的情况下,在严格模式下能够使用with语法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/619278.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

asp.net高校食谱管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net高校食谱管理系统 是一套完善的web设计管理系统,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为vs2010,数据库为sqlserver2008,使用c#语言 开发 asp.net高校食谱管理系统VS开发s…

Spring - Bean的实例化流程及生命周期

文章目录 Bean的实例化流程及生命周期一、Bean实例化基本流程1.1 Bean实例化基本流程1.2 总结 二、 Bean 后处理器2.1 介绍2.2 BeanFactoryPostProcessor Bean工厂后处理器2.2.1 入门2.2.2 Bean工厂后处理器注册BeanDefinition2.2.3 BeanDefinitionRegistryPostProcessor专门注…

2023年软件测试工程师如何提升?测试工程师破局进阶...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 熟练掌握基本的测…

Java反编译工具Jad的下载与使用示例

场景 Java反编译工具-JD-GUI下载以及使用: Java反编译工具-JD-GUI下载以及使用_霸道流氓气质的博客-CSDN博客 上面讲过Java反编译工具JD-GUI的使用,如果使用jad并通过命令如何实现反编译。 为了验证Java开发手册中为什么不推荐使用进行字符串拼接&…

基于轻量级卷积神经网络模型开发构建中国象棋棋子识别系统

关于棋类相关的AI类型的项目在我之前的文章中也有过不少的实践开发经历,这里就不再赘述了,感兴趣的话可以自行移步阅读即可: 《YOLOV5融合SE注意力机制和SwinTransformer模块开发实践的中国象棋检测识别分析系统》 《基于轻量级YOLO开发构建…

【IP技术】什么是IP地址?

一、IP地址概念 IP地址是一个32位的二进制数,它由网络ID和主机ID两部份组成,用来在网络中唯一的标识的一台计算机。网络ID用来标识计算机所处的网段;主 机ID用来标识计算机在网段中的位置。IP地址通常用4组3位十进制数表示,中间用…

(论文阅读)Chain-of-Thought Prompting Elicits Reasoning in Large Language Models

论文地址 https://openreview.net/pdf?id_VjQlMeSB_J 摘要 我们探索如何生成一个思维链——一系列中间推理步骤——如何显著提高大型语言模型执行复杂推理的能力。 特别是,我们展示了这种推理能力如何通过一种称为思维链提示的简单方法自然地出现在足够大的语言模…

运用自动化测试脚本,测试下CSDN的登录功能模块

目录 前言 python程序目录 账号密码登录模块 测试用例执行模块 运行结果示例 前言 自动化测试的重要性越来越受到人们的重视,因为它可以提高测试效率、降低测试成本并减少人为错误的出现。为了满足这个需求,越来越多的公司开始采用自动化测试来保证…

项目跑不起来

Sa-Token/sa-token-core/src/main/java/cn/dev33/satoken/temp/SaTempUtil.java:10:8 java: 写入cn.dev33.satoken.temp.SaTempUtil时出错: Output directory is not specified 写入cn.dev33.satoken.temp.SaTempUtil时出错: Output directory is not specified 答案&#xf…

c++的概述

c是面向对象、泛型编程。 1、 第一个c程序&#xff1a; #include <iostream>using namespace std;int main(int argc, char *argv[]) {//cout代表终端输出设备 endl换行cout << "Hello World! " << endl;cout << 100 << endl;std:…

Element-Plus el-upload组件批量上传图片问题记录

上传图片组件踩坑记录 1. 第一次尝试 最初的写法如下&#xff0c;在本地跑的时候每上传一张图片调一次接口&#xff0c;虽然图片回显正常了&#xff0c;但是每次都会自动多调一个如下图所示的apply-login 报错404&#xff0c;部署到测试环境后&#xff0c;就是每次都报错&…

linux(信号产生中)代码来验证

我们应该如何理解我们调用系统接口并不是简单的调用系统接口这么简单就完事了---我们有时候也是需要使用由操作系统为我们提供的操作系统的层面的数据类型 sigset_t 我们来介绍一种类型&#xff0c;从我们之前学的图来看&#xff0c;每一个信号不管是在block表还是在pending表…

鄂尔多斯市政务协同办公平台,让全市政务更协同高效

近年来&#xff0c;国家高度重视数字政务建设&#xff0c;以数字化推进国家治理体系和治理能力现代化&#xff0c;助力建设人民满意的服务型政府。 2018年&#xff0c;国务院办公厅印发《进一步深化“互联网政务服务”推进政务服务“一网、一门、一次”改革实施方案》&#xf…

这份阿里巴巴内部Spring Cloud Alibaba全套笔记,几乎涵盖了所有操作

Spring Cloud Alibaba 是阿里巴巴提供的微服务开发一站式解决方案&#xff0c;是阿里巴巴开源中间件与 Spring Cloud 体系的融合。 Springcloud 和 Srpingcloud Alibaba 区别&#xff1f; SpringCloud&#xff1a; 部分组件停止维护和更新&#xff0c;给开发带来不便;SpringCl…

缓存数据一致性探究

缓存是一种较低成本提升系统性能的方式&#xff0c;自它面世第一天起就备受广大开发者的喜爱。然而正如《人月神话》中的那句经典的“没有银弹”中所说&#xff0c;软件工程的设计没有银弹。 就像每一次发布上线修复问题的同时&#xff0c;也极易引入新的问题&#xff0c;自缓存…

一文让你明白软件测试该怎样入门?

我认为入门软件测试需要四个方面的知识or技能&#xff0c;它们是&#xff1a;业务知识、职业素养、基础知识、技术知识。 职业素养是一切的根基&#xff0c;因为人在职场就必须拥有必要的职业素养&#xff0c;软件测试工程师也不例外。基础知识和技术知识是两大支柱&#xff0…

【正点原子STM32连载】 第二十九章 DMA实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第二十…

第26节:cesium 高程数据下载(含源码+视频)

本节主要讲解高程dem数据下载方式 下载网址1: http://srtm.csi.cgiar.org/download 下载较慢,含全球高程数据 下载网站2:地理空间数据云 下载速度快,中国科学院计算机网络信息中心公布数据,正式可靠 下面主要介绍地理空间数据云的下载方式。 1.登录 2.选择高级检索 3.选择数…

【改进的多同步挤压变换】基于改进多同步挤压的高分辨率时频分析工具,用于分析非平稳信号(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

一份配置轻松搞定表单渲染,配置式表单渲染器在袋鼠云的实现思路与实践

前段时间&#xff0c;袋鼠云离线开发产品接到改造数据同步表单的需求。 一方面&#xff0c;数据同步模块的代码可读性和可维护性较差&#xff0c;导致在数据同步模块开发新功能和定位问题的效率很低。另一方面&#xff0c;整体规划上&#xff0c;希望在对接新的数据源时&…