Ответы пользователя по тегу JavaScript
  • Как грамотно написать интерпретатор?

    1. Как в рантайме правильнее разграничить вызов нативных (реализованных на Java) функций и вызов функций на JavaScript (это весьма разные сущности)?

    Ну сделай разные классы для разных функций. JS динамически типизированный, так что в основном ты все равно будешь работать с каким-нибудь базовым абстрактным JsValue, от него и унаследуй классы функций. У класса JsValue сделай метод

    JsValue call(scope: JsScope, context: JsValue, args: ArrayList<JsValue>)

    который кидает TypeError: бла-бла-бла is not a function, а в классах функций (JsNativeFunction и JsFunction) переопредели его чтобы возвращал что-то.

    2. Как оптимальнее хранить scopes? Через Hashtable/HashMap в виде вектора (имитация стека) - нормальное решение?

    Я не эксперт, но я делал скоуп в виде хешмапа со ссылкой на родительский скоуп (и так по ссылкам можно было соответственно дойти до глобального скоупа), вроде нормальный вариант.

    3. Как правильно организовать поиск функций в цепочке прототипов объекта? Например, мы ищем функцию; она находится в прототипе, ссылку на который мы храним. Но при вызове такая функция должна работать с полями данных исходного объекта, а не прототипа, или прототипа прототипа и т.д. В JavaScript всё будет в такой ситуации работать корректно, а как такое грамотно эмулировать?

    Не вижу проблемы. x.foo(42) разворачивается во что-то типа этого:

    JsObject xVar = scope.getVar("x");
    xVar
        .attr("foo")    // ищет атрибут в объекте или в прототипе
        .call(scope, xVar, Arrays.asList(JsInt(42)));

    Второй параметр метода call - это и есть контекст, то есть объект у которого вызывается метод.

    4. Эффективный алгоритм разбора выражений тоже не помешал бы. Как быстро разобрать строку, зная приоритеты операторов, корректно выделить все круглые скобки, которые могут быть вложены друг в друга, и т.д. Ссылки на любую литературу, в том числе англоязычную, приветствуются.

    Тут вряд ли что-то толковое подскажу, кроме как посмотреть в сторону ANTLR и аналогов.

    P. S.
    Немного литературы по теме
    Ответ написан
  • Зачем использовать functor?

    Функтор, в контексте функионального программирования — это интерфейс (или тайпкласс), который может быть реализован для разных типов. Чтобы тип мог имплементировать функтор, он должен иметь кайнд * -> * (то есть это должен быть дженерик с одним параметром) и для него должна быть реализована функция map:

    map :: Functor f => (a -> b) -> (f a -> f b)

    Имя и сигнатура могут отличаться в зависимости от реализации, например в Haskell эта функция называется fmap, а в Fantasy Land сигнатура выглядит так:

    map :: Functor f => f a ~> (a -> b) -> f b

    Также для функции/метода map должны выполняться определённые законы, не буду их копировать сюда, просто оставлю ссылку: https://github.com/fantasyland/fantasy-land#functor

    Несколько примеров функторов:
    • Arraymap применяет функцию к каждому элементу массива.
    • Futuremap применяет функцию к значению когда оно зарезолвится.
    • Maybemap применяет функцию к значению, если оно существует, иначе возвращает Nothing.
    Ответ написан
    1 комментарий
  • Как создать get и set в функции-конструкторе?

    function Foo() {
      let counter = 0;
      
      Object.defineProperty(this, "counter", {
        get() {
          return counter++;
        }
      })
    }
    
    const foo = new Foo();
    
    foo.counter;    // => 0
    foo.counter;    // => 1
    Ответ написан
    2 комментария
  • Как собрать свой объект из Interface?

    activityType это же массив, у него нет поля name
    Ответ написан
  • С чего начать в функциональном программировании на js?

    Еще я понял, что ramda это самая близкая к фп библиотека , а другие что то типо либ общего назначения.

    Это так. В Ramda все функции каррированы из коробки, аргументы передаются в удобном для функционального стиля порядке, функции не мутируют данные, а создают новые копии.

    Подскажите с какой библиотеки лучше начать.

    Определённо, с Ramda.

    А может Elm?

    Если уже знаете JS то проще будет начать с Ramda. Хотя Elm жёстче в плане соблюдения правил функционального подхода.

    Еще такая проблема , что я обычно читаю документацию с плагином google translate и нормально понимаю смысл, но с фп у меня так не выходит (пытался читать документацию ramda и underscore). Может сталкивались с переводами документаций или их подобиями?

    Учите английский. Без него изучать программирование в любом случае затруднительно.

    Алсо, маст хэв для ФП в JS - Fantasy Land (можно добавить ещё Static Land). Но это следующий уровень, после того как освоите основные приёмы ФП и прочитаете пару статей о монадах, функторах и т.д.
    Ответ написан
    Комментировать
  • Как написать метод, чтобы конвертировать объект в массив?

    function toArray(obj) {
      const arr = [];
      for (let key in obj) {
        arr[key] = obj[key];
      }
      return arr;
    }

    P.S. Прототипы встроенных объектов не расширяют, вместо этого используйте отдельную функцию.
    Ответ написан
    Комментировать
  • Прототипное наследование быстрее или функциональное?

    Ну во-первых, как уже было отмечено, никакого "функционального наследования" не существует. Во-вторых, наследование в принципе костыль. В 2к17 вместо наследования используют композицию и делегирование.
    Ответ написан
    Комментировать
  • Что изучать jQuery или чистый JavaScript?

    Глупый вопрос. Конечно в первую очередь нужно учить язык, а потом уже, при необходимости, библиотеки/фреймворки используемые с этим языком. Ну и вообще JQuery сейчас теряет актуальность, так что делать упор на изучение JQuery значит закопать себя в вёрстке лендингов, тогда как с хорошим знанием JS и его паттернов можно пилить всякие интересные крутые штуки.
    Ответ написан
    Комментировать
  • Циклы, Вынести переменную или объявлять внутри при каждой итераиции?

    от 1 до 1000 элементов

    Количество смешное, даже если разница будет, Вы её не заметите на таком числе элементов. В общем, не страдайте фигнёй и пишите так, как логичнее - то есть объявляйте переменную внутри блока.

    Если уж интересует производительность, то это очень зависит от используемого движка. У меня в SpiderMonkey (Firefox), например, второй вариант при миллиарде элементов в среднем на сотню миллисекунд быстрее (что-то вроде 916ms для первого и 832ms для второго варианта). Но в V8 и Chakra результаты могут быть другими. Да и кто Вам мешает свои тесты провести?

    Но всё-таки, даже при миллиарде элементов разница незначительная. Стоит ли заморачиваться такими вещами при тысяче элементов, если разница будет меньше одной миллисекунды (то есть по факту разницы не будет)?
    Ответ написан
    Комментировать
  • Как пропускать элементы в map?

    На самом деле, если не боитесь изучить новую абстракцию (не такую уж и сложную, на самом-то деле), посмотрите на трансдьюсеры. Эта абстракция как раз позволяет комбинировать функции вроде filter и map без лишних проходов по коллекции. На Clojure[Script] Ваш пример выглядел бы следующим образом:
    (def exists #(.exists (clojure.java.io/as-file %)))
    
    (def process-files
      (comp
        (map #(do-something %)))
        (filter #(exists (:path %))))
    
    (sequence process-files audios)

    В JS трансдьюсеры реализованы в Ramda, выглядеть на JS это будет как-то так:
    import { compose, filter, into, map } from 'ramda';
    
    const processFiles = compose(
      map(audio => doSomething(audio)),
      filter(audio => fs.existsSync(audio.path))
    );
    
    into([], processFiles, audios);


    UPD: Есть ещё такое ad-hoc решение: написать функцию-хелпер filterMap, которая внутри будет императивной, но при использовании будет выглядеть вполне нормально:
    function filterMap(filterFn, mapFn) {
      return arr => {
        const newArr = [];
        for (let x of arr) {
          if (filterFn(x)) newArr.push(mapFn(x));
        }
        return newArr;
      }
    }

    Использование:
    const processFiles = filterMap(
      audio => fs.existsSync(audio.path),
      audio => doSomething(audio)
    );
    
    processFiles(audios);

    Но такое решение куда менее расширяемо чем решение с трансьюсерами, да и на мой взгляд менее красиво.
    Ответ написан
    Комментировать
  • Объявление методов прототипа - как лучше?

    class Human {
      constructor(name) {
        this.name = name;
      }
    
      sayName() {
        console.log(`My name is ${this.name}`);
      }
    }
    Ответ написан
  • Как более эффективно работать с dom javascript?

    Имхо экономия на спичках. Чтобы эффективнее работать с DOM, используйте Vritual DOM.
    Ответ написан
    1 комментарий
  • Как собрать такую фиксированную функцию?

    Как верно заметил Rsa97, чтобы проверять правильную вложенность скобок, открывающие скобки надо класть на стек:

    function validBraces(text) {
        const stack = [];
    
        for (let c of text) {
            if ('([{'.includes(c)) stack.push(c);
            else if (')]}'.includes(c)) {
                if ('([{'.indexOf(stack.pop()) !== ')]}'.indexOf(c)) {
                    return false;
                }
            }
        }
        return true;
    }
    Ответ написан
    Комментировать
  • Angular 2 typesript или es6?

    ES2015 ⊂ TypeScript

    TypeScript включает в себя если не весь, то почти весь ES2015 + всякие типы, интерфейсы, абстрактные классы и так далее. Не обязательно пользоваться всеми этими фичами, хотя мне например проще написать немного лишнего кода (описать интерфейсы, объявить типы) и поймать часть ошибок на этапе компиляции, чем вылавливать их в рантайме.
    Ответ написан
    Комментировать
  • Как улучшить знание JS?

    Можете попробовать поковыряться в демках с codepen.io.
    Вот, например, калькуляторы: codepen.io/search/pens?q=calculator
    А здесь показано написание калькулятора на JS от начала до конца: thecodeplayer.com/walkthrough/javascript-css3-calc...
    Ответ написан
    1 комментарий
  • Как удалить второй title из кода страницы?

    $("title")[1].remove()
    Ответ написан
    Комментировать
  • Зачем создают "min" framework?

    чтобы айфоны с мобильным интернетом быстрее загружали либу
    Ответ написан
    Комментировать
  • Как использовать ECMAScript 6?

    Babel
    Ответ написан
    Комментировать
  • Как наследовать объект самовызывающейся функции?

    Это называется фабрика объектов:
    function Basket(option1, option2, ...) {
        var basket = [];
    
        return {
            "option1": option1,
            "option2": option2,
            ...
        }
    }

    var basket = Basket(function() {...}, function() {...}, ...)
    Ответ написан
    Комментировать
  • Как разбить число на части?

    function numberFormat(num) {
      if (typeof num !== "string") {
        return numberFormat(num.toString())
      } else {
        if (num.length < 4) {
          return num
        } else {
          return numberFormat(num.slice(0, num.length - 3)) + " " + num.slice(num.length - 3)
        }
      }
    }
    Ответ написан
    1 комментарий