Будет работать, но это уже не литерал )) и свойство o.level1.sub неравноправно и ненаглядно по отношению к level1. Просматривая быстро глазами свойства объекта мы вряд ли тело функции будем смотреть, чтобы понять, что объект расширился. Это пока всех ближе, к тому синтаксису как я сам делаю сейчас :) и похоже на вариант предложенный quakin:
var o = {
level1: function(){
o.level1.sub = 2; // this.sub если без new вызывать
return function(){};
}()
}
На момент объявления свойств и методов объекта "o" самого объекта не существует в области видимости, поэтому явно присвоить свойство или метод этому объекту нельзя. Возможно для того, что бы код лучше читался, не стоит искать мудреные конструкции, а объявить объект так, как он объявлен в вопросе.
p.s Вы пробовали ваш вариант запускать?
p.p.s. На всякий случай, если вы любитель экзотики:
var o = ({
level1: function(){},
extend: function(){
this.level1.sub = 2;
delete(this.extend);
return this;
}
}).extend()
Если в вопросе не было опечатки,
и вместо level2 оба раза встречается level1, тогда сработает такой код:
var o = {
level1 : new function(){this.sub=2; /*...*/ },
};
В таком случае можно напрямую обращаться к свойству o.level1.sub,
но стоит помнить, что вызвать функцию o.level1() не получится,
т.к. o.level1 в этом случае — объект, созданный через конструктор («new function»),
а код на месте /*...*/ выполнится один раз в момент создания объекта.
Да, ровно и также как если бы level1 была не функцией, а например число. Т.е. логически скорее всего через литерал нельзя так определить сразу. Использовать вложенность не хочется, как раз по причине, что через литерал все равноправно и наглядно видно.
В вашем примере обращаться к функции можно будет, если конструктор вернет новую функцию, но это не через литерал уже.
function callable(dict) {
var run = dict.$run;
foreach (var k in dict)
run[k] = dict[k];
return run;
}
var o = {
level1: callable({
$run: function() {...},
sub: 2
})
};
Как мне кажется, получилось достаточно похоже на литерал.