Reflect API — забутий герой ES2015

Скрізь та давно говорять про ES2015, хоч на дворі вже 2017 рік, є ще люди не знайомі з цим стандартом. ES2015 приніс багато нового в світ JavaScript, щось подхватилось моментально, що продовжує залишатися в тіні.

Всі ми любимо використовувати модульний підхід ES6, стрілочні функції, let та const, promises, класи, від деструктуризації багато прийшли в захват. Рідше згадується про новий тип Symbol, генераторах, Map, Set, WeakMap, WeakSet, і багато чого ще.

На мій погляд основна причина рясного використання одних нововведень, і вкрай рідкісне використання інших — це практична необхідність. Я не можу пригадати випадку, коли мені б знадобилося використовувати Map замість звичайних масивів або об'єктів. Генератори я знаходжу корисними і класно що в JS їх додали, але знову ж, у моїй практиці написання Front-End'а, я якщо і знаходив їм застосування, то не частіше ніж пару разів. Бути може я просто не змінив мислення і використовую старі підходи до розробки під маскою let, const, arrow function, класів, але поговорити я хочу все ж не про це.

Незважаючи на всі ці WeakSet, генератори і Symbol'и, на мій погляд найбільш всіх осторонь виявилися Reflect API та Proxy об'єкти. Давайте згадаємо про них, а раптом там щось корисне.

Почнемо з того що Reflect це не конструктор. Це як зрозуміло з назви набір методів для роботи з об'єктами подібно об'єкту Math.

Пропоную освіжити пам'ять і коротко пройтися по деяких методів Reflect API:

  • Reflect.apply(target, this, args)

    Тут все зрозуміло, метод для виклику функції з зазначеним контекстом. Приймає функцію, контекст, аргументи у вигляді масиву.

    function countAmountScore(audienceScore, juryScore) {
    return this.userScore + audienceScore + juryScore;
    }
    let subZeroRating = Reflect.apply(countAmountScore, {userScore: 15}, [5, 10]); // виведе 30

  • Reflect.construct(constructor, args, prototype)

    За допомогою цього методу можна викликати конструктор без використання оператора new. Головною «плюшки» використання цього методу на мій погляд є третій, необов'язковий параметр. Це вказівка прототипу до обращаемой функції-конструктору.

    function checkFullName(name, surname) {
    this.name = name;
    this.surname = surname;
    this.getName = function() {
    return `${this.name} ${this.middleName} ${this.surname}`
    };
    }
    
    function addMiddleName () {}
    
    addMiddleName.prototype.middleName = 'Ілліч';
    
    let Lenin = Reflect.construct(checkFullName, ['Володимир', 'Ленін'], addMiddleName);
    Lenin.getName(); // виведе "Володимир Ілліч Ленін"

  • Reflect.defineProperty(object, property, attributes)

    Цей метод діє аналогічно однойменним методом у Object, з тією лише різницею, що метод Reflect.defineProperty повертає булевое значення, в залежності від успіху або невдачі присвоєння.

    Першим аргументом функції йде об'єкт до якого йде присвоєння властивості, другим — ім'я властивості, третім — опції або просто значення присвоюється властивості.

  • Reflect.deleteProperty(target, property)

    Метод для видалення властивість та інших сутностей, працює аналогічно delete, з тією лише різницею, що повертає булевое значення залежно від успіху або невдачі видалення.

  • Reflect.enumerate(object)

    Цей метод не рекомендується використовувати, оскільки він є «застарілим» (obsolete), якщо вірити документації, але в деяких браузерах все ще може працювати.

    Цей метод працює подібно for..in, але замість того щоб проходиться по об'єкту — повертає ітерацію, простіше кажучи — генератор. Але так як багато інтерпретатори цей метод не розуміють — розглядати його немає сенсу.

  • Reflect.get(object, property, this)

    Метод служить для одержання властивості об'єкта, застосовна до масивів.

    // Object
    var obj = { x: 1; y: 2 };
    Reflect.get(obj, 'x'); // 1
    
    // Array
    Reflect.get(['zero', 'one'], 1); // "one"
    
    // Proxy with a get handler
    var x = {p: 1};
    var obj = new Proxy(x, {
    get(t, k, r) { return k + 'bar'; }
    });
    Reflect.get(obj, 'foo'); // "foobar"

  • Reflect.set(object, property value, this)

    Працює аналогічно методу Reflect.get з тією лише, що задає вказане значення, а не отримує його.

    Метод Reflect.set повертає булевое значення залежно від успіху або невдачі присвоєння значення.

  • Reflect.has(object, property)

    Потрібний для перевірки існування властивості в об'єкті. Повертає булевое значення.

    let building = {
    __proto__: {
    type: "castle"
    },
    age: 300
    };
    console.log(Reflect.has(building "age")); // виведе true
    console.log(Reflect.has(building "type")); // виведе true

  • Reflect.ownKeys(object)

    Метод Reflect.ownKeys — повертає ключі елементів об'єкта, у вигляді масиву. Успадковані властивості ігноруються.

    let obj = {
    name: "Іван Федорович Крузенштерн",
    rank: "Адмірал",
    __proto__: {
    yearOfBirth: 1770
    }
    }
    
    let objKeys = Reflect.ownKeys(obj);
    console.log(objKeys.length); // виведе 2
    console.log(objKeys[0]); // виведе name
    console.log(objKeys[1]); // виведе rank
    
У статті були наведені не всі методи з Reflect.API, решта здалися мені майже цілком аналогічними однойменною методів побратима Object.

Позитивний герой чи негативний цей Reflect.API, чи є в ньому щось корисне — кожен визначить сам. Безумовно цей програмний інтерфейс має право на життя.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.