如何动态执行JS

4 篇文章 0 订阅
3 篇文章 0 订阅

引言:随着行业发展,技术更新,生产结构发生变化,低代码技术又重新站上了舞台,开发者们成为了舞台幕后的操纵者。在web端的低代码开发工具中,js占据了重要的位置,而【动态执行】也成为了低代码开发工具中不可或缺的一部分。本文记录了js的动态执行方法,以备不时之需。

方法1:eval()

eval()函数来解析执行字符串代码,eval()函数接受一个字符串参数,将字符串解析为JavaScript代码并执行。

let a = ()=>{
    console.log(123);
    eval("console.log(234)");
    console.log(456);
}

注意:安全隐患,确保传入的代码串是安全的

方法2:Function

new Function('a', 'b', 'return a + b')(1,2); // 输出 3

方法3:setTimeout和setInterval

利用etTimeout()函数和setInterval()函数可以接受字符串参数的特性,可以建立异步的动态执行代码

setTimeout("console.log('Hello, world!')", 1000);

方法4:ES6中的模版字符串(Template Literals)

其实这里只是用到了模版字符串中解析变量的能力来存储动态变化的代码

let code = `
  let a = 1;
  let b = 2;
  console.log(a + b);
`;

eval(code); // 输出 3

方法5:with语句

with语句是JavaScript中的一种特殊语法,它可以将一个对象添加到作用域链的头部,从而可以直接访问该对象的属性和方法,而无需使用对象名称。with的这种特性在某些场景下是很有用的,比如vue源码中动态生成render代码的场景,如下:

export function generate (
 ast: ASTElement | void,
 options: CompilerOptions
): CodegenResult {
 const state = new CodegenState(options)
 const code = ast ? genElement(ast, state) : '_c("div")'
 return {
  render: `with(this){return $[code]}`,
  staticRenderFns: state.staticRenderFns
 }
}

注意:使用with语句动态执行代码需要谨慎使用,因为它会修改作用域链,可能会影响到其他代码的运行,同时也会降低代码的可读性和可维护性。

方法6:AsyncFunction和GeneratorFunction

AsyncFunction和GeneratorFunction是Function构造函数的后代,它们分别用于动态生成异步函数和生成器函数,语法与Function构造函数类似

const GeneratorFunction = function* () {}.constructor;

const foo = new GeneratorFunction(`
  yield 'a';
  yield 'b';
  yield 'c';
`);

let str = '';
for (const val of foo()) {
  str = str + val;
}

console.log(str);

const AsyncFunction = async function () {}.constructor;
let code = `
  return new Promise(resolve => {
    setTimeout(() => {
      resolve("Hello, world!");
    }, 1000);
  });
`;

let asyncFn = new AsyncFunction(code);

asyncFn().then(result => {
  console.log(result); // 输出 "Hello, world!"
});

方法7:动态创建script标签

let code = 'console.log("Hello, world!");';
  let script = document.createElement('script');
  script.text = code;
  document.head.appendChild(script);

注意:使用script标签动态执行代码需要考虑到代码的作用域和依赖的问题,因为代码是在全局环境中执行的,可能会影响到其他代码的运行

方法8:新语法import(‘./xx.js’)

import()函数是ES6中引入的动态导入模块的方式,可以动态地加载一个JavaScript模块,并返回一个Promise对象

import('./module.js').then(module => {
  // 使用module中的代码
}).catch(error => {
  // 加载模块失败
});

import()函数接受一个字符串参数,表示要加载的模块文件路径。
注意:import()函数目前还不是所有浏览器都支持,需要使用Webpack等工具进行打包,或者使用Polyfill库进行兼容性处理。

方法9:Worker

Worker是在Web Worker API中引入的一种机制,它可以在独立的线程中运行JavaScript代码,并且可以与主线程进行通信。在Worker线程中可以动态执行代码,而且不会对主线程造成影响.

// 新建Worker线程
let worker = new Worker('worker.js');

// 发送消息给Worker线程,要求执行某个函数
worker.postMessage({ type: 'execute', code: 'console.log("Hello, world!")' });

// 监听Worker线程的消息
worker.onmessage = event => {
  // 处理消息
};

注意:使用Worker方式动态执行代码需要考虑到线程之间通信的问题,并且需要避免访问主线程的全局变量和DOM等资源,因为Worker线程和主线程是相互独立的。

方法10:Proxy

Proxy是ES6中引入的一种元编程机制,它可以拦截对象的各种操作,包括读取、赋值、调用等。利用Proxy,可以动态地创建一个代理对象,拦截对这个对象的操作,并在拦截器中执行代码.

let code = `
  let a = 1;
  let b = 2;
  console.log(a + b);
`;

let proxy = new Proxy({}, {
  get(target, property) {
    if (property === 'execute') {
      return () => {
        return eval(code);
      };
    }
  }
});

方法11:document.write()

直接把代码写入到HTML文档中

以上就是目前我了解到关于js动态执行的方法。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wl_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值