1. JavaScript / Говнокод #27505

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    class Animal {
        move(distanceInMeters = 0) {
            print(`Animal moved ${distanceInMeters}m.`);
        }
    }
    
    function main() {
        const dog = new Animal();
        dog.move(10);
    
        const dog2 = Animal();
        dog2.move(11);
    }

    Загадка дня... кто знает что первый вызов конструктора отличается от второго?

    Запостил: ASD_77, 07 Июля 2021

    Комментарии (23) RSS

    • жду варианты. для подсказки даю дамп. https://pastebin.com/2kjkCRX6
      Ответить
      • Не глядя в дамп: new выделяет место в куче, а второй вызов кучу не использует?
        Ответить
        • а второй размещает обьект в стеке :)
          Ответить
          • Я уже подглядел в дамп...
            Ответить
          • Вдохновлено C++...

            Интересно, а как в твоем JS-подобном языке работают замыкания (или работали бы)? Если они используют ссылки на внешние переменные и их вызвать в тот момент, когда память из под этих самых переменных почистилась, то как поведет себя программа? Будет использовать мусорные данные, упадет (segfault десу)? Либо на этапе компиляции есть escape analysis, после которого решается какие переменные выделить в куче, а какие на стеке (как в Go, ЖС например) либо генерится ошибка компиляции (как в Rust - память под части структуры должна быть занята не на более короткий срок чем под саму структуру)?
            Ответить
            • почему нельзя всё в куче и ГЦ, а потом оптимизировать?
              Ответить
              • Ну собственно для этого и нужен

                > escape analysis
                Ответить
                • при этом невозможно
                  >Если они используют ссылки на внешние переменные и их вызвать в тот момент, когда память из под этих самых переменных почистилась
                  Ответить
                  • Если память под них выделить в стеке, то она почистится после возврата из функции, а замыкание будет использовать мусорные данные ссылаясь на эти переменные (или упадет с segfault-ом) при его вызове. На куче - ок. Вопрос в том, решает ли компилятор JS-подобного языка от автора за программиста какие переменные из функции выделять на стеке, а какие в куче на основе того, а используются ли они за пределами скоупа функции (например в возвращаемом замыкании).
                    Ответить
                    • Если у вас escape analysis, то решает

                      Если же решает программист (как в случае С++) то программист же и решает как и какие переменные захватывает замыкание (по ссылке или копируя по значению)
                      Ответить
            • работает точно также как ламбда в С++ только по "&"
              Ответить
              • Какой сегфолт )))

                Или это временная подпорка?
                Ответить
                • я пока не решил - хочу ли я разрешать возвращать функцию с пойманными переменными в "return".
                  Ответить
    • вторая конструкция невалидная вроде
      Ответить
      • попробуй выполнить код
        Number()
        Ответить
        • и что?
          Number не определён с ключ словом "class"

          Number это хуёвая конструкция, которая с "new" создает объект, а без new кастит, как и String, как и прочая херня
          Ответить
    • Вообще без new будет просто фукнция, но будет ли она работать с class -- хз, вероятно нет
      Ответить
      • В ЖС ES6 class - ето сахарок для функции-конструктора с прототипом. А new в ЖС делает следующее:

        1) Создает объект;
        2) Прокидывает его как this вызываемой функции;
        3) Вызывает функцию;
        4) Если функция ничего не вернула (или в понятиях ЖС - вернула undefined), то new возвращает указатель на свежесозданный объект, иначе - то что вернула функция;

        Значит если вызвать Animal без new, то вернется undefined, потому что идет просто вызов функции, без учета контекста свежесозданного объекта. И на строчке "dog2.move(11)" программа упадет. Ну, если аффтар следовал такой спеке.
        Ответить
        • class A {constructor(){this.b = '1'}}
          const c = A() // Uncaught TypeError: Class constructor A cannot be invoked without 'new'


          мы вам перезвоним
          Ответить
          • Спасибо за еще один день без наступления на грабли.
            Ответить
        • Поправка: если функция вернула примитив, то оный примитив заворачивается в соответствующий объект.
          Ответить

    Добавить комментарий