你需要深入了解一下 JavaScript 的 new Function

d54aef980839441d58e8e100d68771f3.png

前端Q

我是winty,专注分享前端知识和各类前端资源,乐于分享各种有趣的事,关注我,一起做个有趣的人~

公众号

点击上方 前端Q,关注公众号

回复加群,加入前端Q技术交流群

英文 | https://javascript.plainenglish.io/in-depth-js-new-function-syntax-b1957c5dab69

JavaScript技术一直处于不断发展壮大中,如果你是前端开发人员或者JavaScript开发工程师,那么,今天这个知识点,你有必要认真了解一下,它就是“new Function”。

1、语法

语法如下:

let func = new Function ([arg1, arg2, …argN], functionBody);

最后一个参数必须是函数体,其余参数作为传递给函数体的参数。

例如:

let sum = new Function('a', 'b', 'return a + b');
console.log(sum(1, 2)); // the result is 3

我们平时开发 JavaScript 或者 Node.js 的时候,没有理由使用 new Function 构造函数,因为不需要直接使用函数或者 () => {} 箭头函数。

这是否意味着 new Function 语法是一个鸡肋的功能?

千万不要这样想! 因为它绝对不是你想的那样!

 new Function 语法有一个特别强大的特性,使它在 JavaScript 中发挥着不可替代的作用。

有什么特点?也就是函数体的数据格式是字符串,真是不可思议!

不可替代的角色

这里有几个例子来展示 new Function 语法的微妙之处。

01).无效的 JSON 对象字符串合法化

例如,有以下字符串:

let str = `{ "id": 103, name: 'yh', 'date': '2022–07–06' }`;

其中的字符串不符合JSON格式(键值需要双引号),使用JSON.parse()解析会报错。

那么,有没有什么办法可以把这个字符串对象转换成可以解析的JSON呢?

很多人会想到正则匹配然后替换,或者使用eval等渣属性进行处理。

没必要这么麻烦, new Function 上线了,就完美了!

JS 代码如下所示:

console.log(JSON.stringify(new Function('return ' + str)()));
// The return result is: '{"id":10393,"name":"yh","date":"2022–07–06"}'

使用返回语法,你可以轻松地将任意字符串转换为其他 JavaScript数据类型。

02).模板字符串作为模板

比如Vue、React等现在都有自己的模板语法,比如{}语法。

如果我们想直接使用 ES6 自己的语法作为模板语言,就必须使用 new Function 的能力,比如下面的 HTML:

<template id="template">
 ${data.map(function (obj, index) {
return `<p>Article: ${obj.article}</p>
<p>Author: ${obj.author}</p>
`;
 }).join('')}
</template>

我们可以扩展字符串并定义一个名为 interpolate 的字符串方法来将 ES6 语法字符串转换为可执行的 ES6 代码:

String.prototype.interpolate = function (params) {
const names = Object.keys(params);
const vals = Object.values(params);return new Function(…names,`return \`${this}\`;`)(…vals);
};

至此,只要有对应的数据,我们就可以根据<template>模板获取最终编译好的HTML字符串,例如:

const html = template.innerHTML.interpolate({
data: [{
article: 'Article title one',
author: 'y'
 }, {
article: 'Article title two',
author: 'h'
 }]
});
console.log(html);

可以看出,无需任何第三方模板渲染引擎,就能使用复杂语法下的模板渲染效果,原生JS爱好者欣喜若狂。

03).闭包和上下文

new Function 的 body 参数中变量的上下文是全局的,不是私有的,没有所谓的闭包。

例如,下面新函数代码中的值与主函数中的值无关:

function getFunc() {
let value = 'yh';
let func = new Function('console.log(value)');
return func;
}
getFunc()(); // error: value is not defined

如果是常规函数语法,没有问题:

function getFunc() {
let value = 'yh';
let func = function () {
console.log(value)
  };
return func;
}
getFunc()(); // print 'yh'

04).其他

与 new Function 语法类似的是新的RegExp,它可以使用字符串作为正则表达式的内容,特别适合动态匹配,或者增加代码混淆(一些混淆工具可以对字符串进行混淆)。

例如,要匹配以动态值开头的属性值,可以使用以下用法:

let reg = new RegExp('^' + value, 'g');

总结

以上就是我今天跟你分享的关于new Function语法的知识,希望对你有所帮助,如果你觉得有用的话,请记得点赞我,关注我,并将其分享给你身边的朋友,也许能够帮助到他。

最后,感谢你的阅读,期待你的关注,我们一起快乐学编程。

13562b420e7a78812543bc97e4ba703d.png

往期推荐

中高级前端工程师都需要熟悉的技能--前端缓存

9d16b24436edf3067bcba91311e5d21b.png

低代码都做了什么?怎么实现 Low-Code?

75d675b3e17252327e19e5f9901eb2fc.png

中杯超大杯中间的新选择—— Vue2.7 + Vite + TS 实践

b87657c56c802a94ee88de40400eec4a.png


最后

  • 欢迎加我微信,拉你进技术群,长期交流学习...

  • 欢迎关注「前端Q」,认真学前端,做个专业的技术人...

10bdd8416118f56ea0e1269f86d6954d.png

前端Q

本公众号主要分享一些技术圈(前端圈为主)相关的技术文章、工具资源、学习资料、招聘信息及其他有趣的东西...

公众号

a1b2a597be9efd4d61711c53b6a0a327.jpeg

588981e4e9e1056acefb81601fc999db.png

点个在看支持我吧

b0d3dad5b0c85b667b05bf4315caf860.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值