Подтвердить что ты не робот

Возможно ли создание пользовательских операторов в JavaScript?

Во время классов Math мы научились определять новые операторы. Например:

(ℝ, ∘), x ∘ y = x + 2y

Это определяет закон . Для любых вещественных чисел x и y x ∘ y равно x + 2y.

Пример: 2 ∘ 2 = 2 + 4 = 6.


Можно ли определить такие операторы в JavaScript? Я знаю, что функция выполнит эту работу:

function foo (x, y) { return x + 2 * y; }

но я хотел бы иметь следующий синтаксис:

var y = 2 ∘ 2; // returns 6

вместо этого:

var y = foo(2, 2);

Какое самое близкое решение этого вопроса?

4b9b3361

Ответ 1

Короткий ответ - нет. ECMAScript (на основе стандартного JS) не поддерживает перегрузку оператора.

В стороне, в ECMAScript 7, вы сможете перегружать подмножество стандартных операторов при разработке пользовательских типов значений. Ниже приведена слайд-колода от создателя языка и Mozilla CTO Brendan Eich. Это, однако, не позволит использовать суровые операторы, и перегруженное значение будет применяться только к типам значений. < - haha, что не произошло.

Для добавления пользовательских операторов можно использовать сторонние инструменты, такие как sweet.js, хотя для этого потребуется дополнительный этап компиляции.

Я ответил с помощью решения из внешнего JavaScript с помощью esprima - это изменение JavaScript и расширение его, оно не является родным.

Ответ 2

Нет. JavaScript не поддерживает перегрузку оператора. но вы можете сделать метод класса для этого

var mathClass = function(value){
   this.value = value;
}

mathClass.prototype.toLaw = function(){
   return 2 * this.value;
}

var y = new mathClass(2)
2 + y.toLaw(); //2 + 2 * y

Ответ 3

Вы можете добавить псевдооператоры с помощью методов на Number.prototype:

Object.defineProperty(Number.prototype, 'myOp', {
    value: function(that) {
        return this + 2 * that;
    }
});

Затем весь этот синтаксис будет работать

alert( (2).myOp(2) )
alert( 2 .myOp(2) )
alert( 2..myOp(2) )
alert( 2.0.myOp(2) )

2.myOp(2) не работает, потому что период рассматривается как десятичная точка

Ответ 4

Нет. Вы не можете сделать это в JS.

Ближе всего вы можете иметь IMO, чтобы реализовать свой собственный объект, который имеет связующий интерфейс, так называемый "плавный" синтаксис. Таким образом, вы можете действовать так, как будто вы говорите в последовательности.

var eq = new YourEquationObject();

// Then operate like 1 - 2 * 3
eq.add(1).sub(2).mul(3);

Подробности вам до сих пор. Просто давая идею.

Ответ 5

Прочитайте комментарии ниже ответа.

Видимо, вы не можете. Вот что-то близко:

function exec(input) {
    return Function(
        'return ' + input.replace(/∘( *[\d.]+)/g, '+ 2 * $1') + ';'
    )();
}

exec('2 ∘ 2'); // 6

Ответ 6

Немного длиннее, чем короткое: Да, вы можете, но его немного больше, чем то, что вы сделали в классе Math

Чтобы расширить язык с помощью новых конструкций, вы можете использовать трансформатор, например http://esprima.org/ или любой другой. Вам нужно определить свой синтаксис, написать синтаксический анализатор для анализа вашего заявления и, наконец, добавить фактический код для выполнения математических частей. Когда эти части находятся на месте, вы создали новый язык, который работает как javascript, но с добавленной поддержкой оператора .

На самом деле не так сложно добавить новый синтаксис, вот пример facebooks, как они добавляют = > синтаксис функции стрелки

https://github.com/facebook/jstransform/blob/master/visitors/es6-arrow-function-visitors.js

Ответ 7

Я тоже задавал этот вопрос, и вот мой ответ:

function myCustomOperation(string){
var res = String.fromCharCode(9762);
var thing = string.replace(/☢/g," + 10 + ");
thing=thing.replace(/☣/g," * 2 + ");
thing=thing.replace(/☠/g," / 3 * ");
return [eval(thing),string+" = "+eval(thing)];
};
var thing = myCustomOperation("

3 ☠ 4

");
document.write(thing[1]);

Ответ 8

Учитывая несколько новую функцию литералов тегов с шаблонами, которая была добавлена в ES6, можно создавать собственные DSL для обработки встроенных выражений, таких как эти, включая различные алгебраические символы.

ех. (запустить в stackblitz)

function math(strings, x, y) {
  // NOTE: Naive approach as demonstration

  const operator = strings[1].replace(/\s/gi, "");

  if (operator == "∘") {
    return x + 2 * y;
  }
  else if (operator == "^") {
    return Math.pow(x, y);
  }
  else {
    return 'Unknown operator '${operator}'';
  }
}

console.log(math'${2} ∘ ${2}')

Обратите внимание, что поскольку теговые литералы шаблона не обязательно возвращают строки в качестве результатов, они могут возвращать более сложные промежуточные структуры, подобные AST, для создания выражения, которое затем может быть дополнительно уточнено и затем интерпретировано при сохранении близости к языку, специфичному для предметной области. Я не нашел ни одной существующей библиотеки, которая бы делала это для Javascript, но это должно быть интересным и вполне доступным делом из того, что я узнал из теговых литералов шаблонов и использования в таких местах, как lit-html.