如何理解new Function函数,服务器端动态生成客户端脚本
发布于 作者:苏南大叔 来源:程序如此灵动~ 我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...
本文依然描述一个javascript
中的罕见用法,从字符串动态创建一个函数,并可以自定义这个动态生成的函数的参数。写法是非常的奇怪,用法也是非常奇怪。至于具体的使用场景呢,也是非常的罕见。请参考本文的描述。
大家好,这里是苏南大叔的程序如此灵动博客,记录苏南大叔和计算机代码的故事。通过本文的描述可以了解到:js
代码中new Function()
的用法及使用场景。本文测试环境:谷歌浏览器@111.0.5563.111
。
基本使用方式(参数调用)
let str = "return " + "`${name} 大叔`";
let func = new Function("name", str);
var f = func("sunan");
console.log(f);
这个例子使用了重音符和美元符号的写法,参考文章:
也可以不使用这种美元运算符,就是纯正的字符串。比如:
let sum = new Function("a", "return a + 1");
console.log(sum(1));
参数定义及传递
当有两个或三个参数更多参数的时候,可以使用下面的传递方式。
let sum = new Function("a", "b", "return a + b");
console.log(sum(1, 2));
let sum2 = new Function("a , b", "return a + b");
console.log(sum2(1, 2));
变量作用域
虽然这种使用new Function
的方式,和常见的function
定义方式可以相互转换。但是,对于定义在函数外侧的全局变量。两者却有着不同的表现。
function test() {
let _var = "苏南";
let func = new Function("name","return _var + `${name}`");
return func;
}
var ret = test()("hola"); // Uncaught ReferenceError: _var is not defined
console.log(ret);
在目标函数外部定义的某个变量,在使用new Function()
的时候,会报错。
Uncaught ReferenceError: _var is not defined
而下面这样写,并不会报错。
function test() {
let _var = "苏南";
let func = function (name) {
return _var + `${name}`;
};
return func;
}
var ret = test()("hola");
console.log(ret);
特殊使用场景
通过上面的内容学习,可以知道:函数体是字符串所组成的,而且变量只能通过new Function()
参数进行传递。函数体内部无法读取到全局的变量。所以,特殊的使用场景就是,函数体字符串是从服务器动态获得的,然后在客户端先包装成一个函数,然后传递合适的变量,最后再执行对应的字符串。比如:
$.ajax({
url:'https://newsn.net/',
type:'GET',
dataType:'json',
success:function (data) {
let str = data.code; // 注意看这里
let func = new Function("name", str); // 注意看这里
var f = func("sunan");
console.log(f);
},
crossDomain: true,
xhrFields: {
withCredentials: true
}
});
题外话
在这里,穿着长衫的孔乙己表示:那如果把.js
文件在服务器端动态改写也是可以的嘛,何必非要这种客户端请求服务器端,然后再动态将返回的字符串作为函数执行呢?参考nginx
配置:
location / {
rewrite ^/tongji.jsx$ /asset/js/tongji.php last;
}
相关文章
总结
所以,new function()
可以理解为匿名函数,作用是生成另外一个函数。第一个参数是实际函数的参数,第二个参数就是实际函数的函数体。
更多js
的不可思议的知识,请参考:
如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。