【问题标题】:Passing a Function as a String in JavaScript在 JavaScript 中将函数作为字符串传递
【发布时间】:2015-01-02 15:26:04
【问题描述】:

抱歉,如果这有点奇怪......

我有一个用 Java 编写的程序,它利用 ScriptEngine 处理用户提供的 JavaScript 来扩展我的应用程序。然而,这个特定的问题与一般的 JavaScript 相关,而不是 Java 或它的 ScriptEngine,但我只是解释这个来设置上下文。

我有一个函数,它在调用时会返回一个字符串——我们称之为a(),定义如下:

var a = function() {
  return "this is a";
};

当用户使用a() 调用此函数时,它可以正常工作并输出“this is a”。但是,如果用户忘记包含括号,那么它会输出我的实际函数定义 - 因为我不再调用该函数,所以期待这一点。

为了解决这个问题,我将我的 Object 的 toString 方法重新定义为以下内容:

a.toString = function() {
  return a();
};

当我在字符串上下文中使用a 时,这工作正常,因为它隐式调用toString 方法,但如果我尝试将它传递给函数,那么它不会调用toString,我只剩下sun.org.mozilla.javascript.internal.InterpretedFunction

我查看了其他Function.prototype 方法(即applybindconstructor 等)来尝试覆盖在函数传递给另一个函数时调用的方法,但没有一个符合要求。我基本上是在寻找一种将函数转换为字符串类型对象的方法,只要它在没有括号的情况下使用 - 即a === a()。对于可能会问我为什么不将a 定义为一个字符串开头的人,我的函数返回一个由用户提供的其他信息构造的字符串。

也许解决方案是让我的用户编写语法正确的 JavaScript,但我的用户与程序员相差甚远。我还可以添加某种形式的预解析来检查丢失的括号并在使用 ScriptEngine 执行它之前动态添加它们。然而,虽然这两个选项都可以,但我正在寻找一种更简单的方法。

【问题讨论】:

  • 这是一个 XY 问题。你正在修复一个非问题。事实上,高阶函数是一个特性,而不是一个错误。
  • “也许解决方案是让我的用户编写语法正确的 JavaScript”。是的。 “我还可以添加某种形式的预解析,检查丢失的括号并在使用 ScriptEngine 执行它之前动态添加它们。” 这也可以。甚至只是抛出一个错误而不是修复它。
  • 是的,我知道我不应该尝试破解 JavaScript,因为我的用户无法使用正确的语法。文档是确保用户了解正确语法的关键。
  • 一个干净的解决方案是创建你自己的语言,它可以完全按照你和你的用户想要的方式工作。一开始听起来工作量很大,但鉴于大部分基础设施(解析器、字节码解释器等)已经存在,它实际上比尝试修复 javascript 容易得多,并且最终会更加健壮和安全。
  • 我同意并且我已经通过为我的用户创建标记语言为我的大部分应用程序做到了这一点。但是,我允许在我的标记语言中包含一些原生 JavaScript。

标签: java javascript prototype


【解决方案1】:

a.toString 和 a.prototype.toString 都不会让您忘记括号。 .toString 允许你这样做:

var a = function() {
  return "this is a";
};

a.prototype.toString = function () {
  return "something";
};

var A = new a;
alert(A + ''); // something

A.toString = function () {
  return "something else";
};

alert(A + ''); // something else

您不应该在代码中同时希望 a() 和 a 返回相同的东西,这看起来是个非常糟糕的主意。

让 myObject.myVar 返回自定义动态字符串的选项是 defineGetter https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object/defineGetter

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 2015-11-04
    • 1970-01-01
    • 2020-05-01
    相关资源
    最近更新 更多