Недавно я работал над проектом, посвященным почти полностью управляемому клиентом веб-сайту. Очевидно, что Javascript широко используется, и я использовал jQuery поверх него, работать с которым, как оказалось, было абсолютным удовольствием.
Одна из вещей, которая меня удивила, - это то, насколько мне нравится синтаксис объекта JSON и его использование в javascript (выделено jQuery, который использует его повсюду). для тех, кто не знаком с этим, рассмотрим этот краткий пример:
function add(params) {
params.result(params.a, params.b);
}
add({
a: 1,
b: 2,
result: function(value) {
alert(value);
}
});
Конечно, этот пример чрезвычайно надуманный, но он иллюстрирует базовое использование. JSON описывает объект «на лету», передаваемый в данном случае как параметр функции, и даже определяет внутри него функцию для использования в качестве обратного вызова. Я лично считаю эту методологию очень простой в использовании, понимании и создании API-интерфейсов (хотя я знаю, что есть такие, которые со мной не согласны).
Итак, мой вопрос: является ли этот тип синтаксиса уникальным для javascript? Я знаю, что во многих языках есть парсеры JSON (и использовалось несколько), но они не допускают такого рода встроенных объявлений. И конечно, многое из того, что вы можете делать с этим синтаксисом, можно дублировать с помощью именованных параметров на разных языках и лямбда-выражений или указателей функций (на ум приходит Python), но я все еще не нахожу это таким элегантным.
Просто любопытно, спасибо за ответы!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


В C# 3.0 есть нечто похожее в том, что вы можете как создать экземпляр объекта, используя конструктор по умолчанию, так и назначать свойства в одном и том же операторе. На самом деле это всего лишь немного синтаксического сахара, но на самом деле это намного проще, чем объявление нескольких конструкторов только для обработки различных комбинаций настроек параметров. Это выглядит как:
var myObject = new MyClass { Property1 = "value", NumericProperty = 1 };
В C# 3.0 также есть анонимные типы с похожим синтаксисом; они часто используются с LINQ
var query = dataContext.Entity
.Where( e => e.Kind = 1 )
.Select( e => new { e.Name, e.Kind } );
Это приводит к IEnumerable нового анонимного типа со свойствами «Name» и «Kind», которые, в свою очередь, имеют те же типы, что и соответствующие свойства сущности.
Рубисты подойдут:
def add(params) {
params.result(params.a, params.b)
}
add({:a=> 1, :b=> 2}) do |value|
alert(value)
end
Передача необязательного блока - это своего рода странная идиома в ruby. Или вернее твоему примеру.
def add(params) {
params.result(params.a, params.b)
}
add({
:a=> 1,
:b=> 2,
:result=> proc do |value|
alert(value)
end
})
Но концепция встроенной функции происходит от лямбда-исчисления и LISP.
Каноническим примером является Лисп: в Лиспе язык даже не определяется в терминах текста, он определяется в терминах структур данных. На самом деле разницы между кодом и данными нет: код - это просто список, первый элемент которого интерпретируется как операция, а остальные как операнды.
Написание программы - это просто написание списков.
Lua использует «таблицы», которые в значительной степени идентичны объектам javascript.
Синтаксис JSON очень похож на определение сложных структур Perl. И ваш пример будет:
#!/usr/bin/perl
use strict;
use warnings;
use signatures;
sub add($hash) {
$hash->{result}($hash->{a}, $hash->{b});
}
add({
a=> 1,
b=> 2,
result=> sub ($val) {
print "$val\n";
}
});