Расширения языка JavaScript с вызовами функций без скобок - возможны ли они?

Можно ли каким-либо образом сделать что-то вроде этого:

function A() {
    var Loaded = 'loaded';
    raise Loaded;
}
function A_raise(evt) {
    console.log(evt);
}
A.prototype.constructor = A;
A.prototype.raise = A_raise;

Критическая часть, являющаяся линией:

raise Loaded;

2 ответа

Единственный способ получить вызов функции без скобок в JavaScript - это определить свойство setter / getter или переопределить один из специальных методов: toString или же valueOf, Ни в том, ни в другом случае у вас нет действительно хорошего контроля над параметром, который передается в вызов.

function C() {}
C.prototype.valueOf = function () { alert("valueOf called"); };
var c = new C();
// No parentheses
+c;

Вы можете вызвать конструктор без скобок, но, опять же, не можете передавать аргументы.

function f() { alert("f"); }
// No parentheses
new f

Одна из причин, по которой вы не можете это вставить точку с запятой.

f()

это вызов функции, как есть

f
()

а также

if
(x) { }

является действительным условным, потому что if является основной частью языка, но если бы вы могли просто убрать скобки из вызова функции, тогда вставка точки с запятой должна обрабатывать код следующим образом

var x = raise

y

как переменная, инициализированная в результате вызова функции.


Поскольку вы спрашивали о языковых расширениях, в главе 16 спецификации EcmaScript говорится, что переводчикам разрешено добавлять в грамматику языка,

Реализация может расширять синтаксис программы и шаблон регулярного выражения или синтаксис флага. Чтобы разрешить это, всем операциям (таким как вызов eval, использование литерала регулярного выражения или использование конструктора Function или RegExp), которым разрешено генерировать SyntaxError, разрешено демонстрировать поведение, определяемое реализацией, вместо генерирования SyntaxError, когда они сталкиваются с реализацией определенное расширение синтаксиса программы или шаблона регулярного выражения или синтаксиса флага.

так как

 raise foo

не является допустимым выражением или утверждением на языке, они могли бы разрешить это, но они не могли сделать это таким образом, чтобы изменить значение

 raise
 foo

который должен иметь то же значение, что и

 raise;
 foo

поэтому переводчик должен сделать raise новое ограниченное производство, которое проблематично из-за словоблудия:

Ниже приведены единственные ограниченные произведения в грамматике:

Вероятно, это должно быть ненормативным, но это явно не так.

Вы не можете определить новые операторы в JavaScript, поэтому вы не можете создать синтаксис, который вы показываете в A,

Изменить: Из вашего комментария по вопросу ясно, что вы хотите определить новое утверждение / ключевое слово. Нет, ты не можешь этого сделать.


Оригинальный ответ:

Ваша цель внутри A конструктор для вызова A_raise функционировать? Если это так, вы действительно близко. Просто измените:

raise Loaded;

в

this.raise(Loaded);

Живой Пример | Источник

В рамках вызова функции конструктора через new ключевое слово, this это недавно построенный объект, который уже получил свой прототип из функции конструктора prototype имущество. Так this буду иметь raise на нем (через его прототип), и raise будет ссылаться на A_raise функция.

Но опять же, вам нужны парены (и this.).

Другие вопросы по тегам