【问题标题】:Remove the use of eval function from code从代码中删除 eval 函数的使用
【发布时间】:2021-02-06 15:05:02
【问题描述】:

我最喜欢使用的一段代码是:

if (!(eval("this instanceof "+arguments.callee.name)))
  return eval("new "+arguments.callee.name+"(...arguments)");

这段代码允许函数原型在设置时创建自己,就像将自己的结果作为常规函数一样。 (删除了为函数原型键入“新”的要求)

但是,它使用 eval。 有什么办法可以去掉 eval 吗?

另外,有没有办法进一步缩短它?

【问题讨论】:

  • 为什么不能直接输入被调用函数名?
  • 你为什么要它这么有活力?
  • 我希望它是动态的,因为我喜欢将它粘贴到我认为它会使函数声明更漂亮的地方。

标签: javascript eval prototype-programming


【解决方案1】:

是的,那里不需要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;
    // ...
}

这避免了使用evalarguments 伪数组以及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

使用thiscreate 版本避免显式命名构造函数:

    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(..) 一起工作。

【讨论】:

  • 我认为关键是操作不想在那里指定被调用者的名字,因为一些奇怪的原因。你的代码在构造部分仍然有Example
  • 即使没有new.target,您仍然可以在您的示例中使用if (!(this instanceof Example))return new Example(...arguments));
  • @user202729 - 是的,我最初写了if (!(this instanceof Example)),但后来想“也许他们想避免使用函数名”并更改了它...而不是转到 other Example 在代码中。哎呀。 :-)
  • 感谢您的回复,我确实想避免使用函数名称
【解决方案2】:

if(!new.target)return new this[arguments.callee.name](...arguments);

【讨论】:

  • 社区鼓励在代码中添加解释,而不是纯粹基于代码的答案(参见here)。
猜你喜欢
  • 2020-12-03
  • 1970-01-01
  • 2014-09-28
  • 2010-12-07
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多