2013-02-27 3 views
0

Можно, с помощью любых средств, чтобы сделать что-то вроде этого:Расширения языка 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; 
+0

Если это критическая часть, возможно, вы могли бы рассказать нам, что вы подразумеваете под 'raise' (поскольку это не ключевое слово JavaScript). Вы имели в виду 'throw'? Если нет, то что вы имеете в виду? –

+0

Если вам не нравится синтаксис _messy_ JavaScript, вы можете посмотреть на языки, которые компилируются на JavaScript, например CoffeeScript. – Halcyon

+0

Это был всего лишь пример, целью было бы создать новое ключевое слово с именем «raise», которое передает параметр A_raise. – CoryG

ответ

4

Единственный способ получить меньше СКОБКАХ-вызов функции 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 новый restricted production, который является проблематичным из-за многословия:

Ниже приведены лишь ограниченные правила в грамматике:

Это, вероятно, имел в виду, чтобы быть не -нормативно, но это явно не так.

+0

Я понимаю, что пытаться добавить новое ключевое слово на язык сценариев - это немного, чтобы спросить, поэтому я не против взломать способ сделать это, но со свойствами вы не ограничиваетесь использованием знака равенства?Мне бы очень хотелось избежать использования круглых скобок или любых символов - цель - «повысить загрузку»; – CoryG

+0

@CoryG: не с текущим JavaScript, нет. Свойство getter * почти * работает (вам не нужно '='), но вы не можете передать ему аргумент (и это должно быть 'this.raise Loading;' в какой момент, действительно, вы может также бросать на него парсеры). –

+0

Как уменьшить его до "this.raise Загрузка"? Я смог получить его, чтобы «поднять (Loading)»; или "raise = Загрузка"; но ничего, кроме пробела между «рейзом» и «Загрузка», я имею проблемы. – CoryG

1

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

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


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

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

raise Loaded; 

в

this.raise(Loaded); 

Live Example | Source

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

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

+0

Извините, я, вероятно, оставил слишком много деталей в заголовке сообщения - цель состоит в том, чтобы создать новое ключевое слово с именем «raise», которое позволяет избежать необходимости использовать «это». или скобки. – CoryG

+0

@CoryG: Да, просто посмотрел комментарий на вопрос и обновился. Боюсь, вы не можете этого сделать, нет. –