Skip to content

Предложение: использовать нативные методы #3

Closed

Description

@alexeyraspopov

Приветствую! Я очень заинтересовался проектом, и решил изучить его "внутренности". В ридми есть пример кода

var postcss = require('postcss');

var postprocessor = postcss(function (css) {
    css.eachRule(function (rule) {
        if ( rule.selector.match(/::(before|after)/) ) {

            var good = rule.some(function (i) {
                return i.prop == 'content';
            });
            if ( !good ) {
                rule.prepend({ prop: 'content', value: '""' });
            }

        }
    });
});

Позже я нашел, что eachRule — такой же метод как и обычный Array.forEach. Почему бы не использовать нативный метод forEach, вместо самописного?

Обычная работа с массивами позволяет делать много разных вещей, и код может получится "относительно" проще. Например, код из ридми можно написать так:

var postcss = require('postcss');

var postprocessor = postcss(function (css) {
    css.rules.filter(function(rule){
        return rule.selector.match(/::(before|after)/) && rule.every(function(i){
            return i.prop !== 'content';
        });
    }).forEach(function (rule) {
        rule.prepend({ prop: 'content', value: '""' });
    });
});

Кроме того, список свойств для правила можно описать в виде примитивного объекта:

var postcss = require('postcss');

var postprocessor = postcss(function (css) {
    css.rules.filter(function(rule){
        return rule.selector.match(/::(before|after)/) && !rule.props.hasOwnProperty('content');
    }).forEach(function (rule) {
        rule.props.content = '';
    });
});

Activity

  1. ai commented on Nov 4, 2013

    @ai
    Member

    Нативный метод не безопасный — он не создавался с учётом, что кто-то будет менять массив в течении итератора.

    Например:

    a {
      color: white
      background: black;
      border: 1px solid black;
      width: 10px
    }
    rule.decls.forEach(function (decl) {
      console.log(decl.prop);
      decl.remove()
    })

    выведет:

    color
    border
    

    Потому что в процессе цикла размер массива будет меняться.

  2. ai commented on Nov 4, 2013

    @ai
    Member

    Но можно и вручную ходить по массиву. css.rules и rule.decls — обычные массивы.

  3. alexeyraspopov commented on Nov 4, 2013

    @alexeyraspopov
    Author

    Вероятно я не нашел открытые поля rules и decls. По сути это то, что я и искал.

    В случае с decls, если описывать свойства в виде объекта, можно избежать проблемы с методом forEach и удалением:

    Object.keys(rule.decls).forEach(function(key){
      console.log(key);
      delete rule.decls[key];
    });
  4. ai commented on Nov 4, 2013

    @ai
    Member

    Хороший способ! Может быть воспользуюсь им в следующих версиях.

    Но в общем Container.each — это просто алиас к forEach с дополнительными проверками.

    А вот Container.eachDecl и Container.eachRule не совсем аналог forEach — это рекурсивные итераторы проходящие по всем вложенным правилам.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions