从代码中删除对 eval 函数的使用
Remove the use of eval function from code
我最喜欢使用的代码片段之一是:
if (!(eval("this instanceof "+arguments.callee.name)))
return eval("new "+arguments.callee.name+"(...arguments)");
这段代码允许函数原型在设置时创建自己,就像获取自己作为常规函数的结果一样。 (删除了为函数原型键入 'new' 的要求)
但是,它使用eval。
有什么方法可以从中删除 eval 吗?
另外,有没有办法进一步缩短它?
是的,那里不需要 eval
。以下是您在现代环境 (ES2015+) 中的做法:
function Example(...args) {
if (!new.target) {
return new Example(...args);
}
// ...use `args` here, possibly destructuring to local meaningful names e.g.:
const [first, second] = args;
// ...
}
这避免了使用 eval
、arguments
伪数组,以及 arguments.callee
,它们永远不应该使用并且在严格模式下是不允许的。 (严格模式是模块和 类 中的默认模式,并且将是添加到该语言的任何其他新范围中的默认模式。)
如果您愿意,可以继续使用 arguments
伪数组:
function Example(first, second) {
if (!new.target) {
return new Example(...arguments);
}
// ...
}
FWIW,我强烈建议不要 使函数像那样具有双重用途。相反,当您不想使用 new
:
时,请考虑使用 class
语法和 create
函数
class Example {
constructor(biz, baz) {
// ...
}
static create(...args) {
return new Example(...args); // Or `return new this(...args);` or a couple of other choices.
}
}
如果您尝试执行 Example(1, 2)
,则会自动抛出错误,因为 class
构造函数无法像普通函数一样被调用。您可以使用 Example.create(1, 2)
来避免 new
。
使用 this
的 create
版本避免显式命名构造函数:
static create(...args) {
return new this(...args);
}
这是可行的,因为当您执行 Example.create(1, 2)
时,在调用 create
期间 this
指的是 Example.
但是如果您通过 Example.create
周围没有确保它的绑定。例如,const create = Example.create; create(1, 2);
会因 new this(...)
而失败,但会与 new Example(..)
.
一起工作
if(!new.target)return new this[arguments.callee.name](...arguments);
我最喜欢使用的代码片段之一是:
if (!(eval("this instanceof "+arguments.callee.name)))
return eval("new "+arguments.callee.name+"(...arguments)");
这段代码允许函数原型在设置时创建自己,就像获取自己作为常规函数的结果一样。 (删除了为函数原型键入 'new' 的要求)
但是,它使用eval。 有什么方法可以从中删除 eval 吗?
另外,有没有办法进一步缩短它?
是的,那里不需要 eval
。以下是您在现代环境 (ES2015+) 中的做法:
function Example(...args) {
if (!new.target) {
return new Example(...args);
}
// ...use `args` here, possibly destructuring to local meaningful names e.g.:
const [first, second] = args;
// ...
}
这避免了使用 eval
、arguments
伪数组,以及 arguments.callee
,它们永远不应该使用并且在严格模式下是不允许的。 (严格模式是模块和 类 中的默认模式,并且将是添加到该语言的任何其他新范围中的默认模式。)
如果您愿意,可以继续使用 arguments
伪数组:
function Example(first, second) {
if (!new.target) {
return new Example(...arguments);
}
// ...
}
FWIW,我强烈建议不要 使函数像那样具有双重用途。相反,当您不想使用 new
:
class
语法和 create
函数
class Example {
constructor(biz, baz) {
// ...
}
static create(...args) {
return new Example(...args); // Or `return new this(...args);` or a couple of other choices.
}
}
如果您尝试执行 Example(1, 2)
,则会自动抛出错误,因为 class
构造函数无法像普通函数一样被调用。您可以使用 Example.create(1, 2)
来避免 new
。
使用 this
的 create
版本避免显式命名构造函数:
static create(...args) {
return new this(...args);
}
这是可行的,因为当您执行 Example.create(1, 2)
时,在调用 create
期间 this
指的是 Example.
但是如果您通过 Example.create
周围没有确保它的绑定。例如,const create = Example.create; create(1, 2);
会因 new this(...)
而失败,但会与 new Example(..)
.
if(!new.target)return new this[arguments.callee.name](...arguments);