Используйте прокси ES6 для перехвата Object.hasOwnProperty

Я хочу использовать прокси-сервер ES6 для захвата следующего общего кода:

for (let key in trapped) {
    if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
    let value = trapped[key];
    //various code
}

Но после просмотра документации по прокси я Я не уверен, как это сделать, в основном потому, что ловушка has предназначена для оператора in, который, похоже, не используется в приведенном выше коде, а ловушка для операции hasOwnProperty отсутствует.


person GregRos    schedule 06.11.2016    source источник


Ответы (2)


Вы можете использовать getOwnPropertyDescriptor обработчик для захвата hasOwnProperty() вызовов.

Пример:

const p = new Proxy({}, {
  getOwnPropertyDescriptor(target, property) {
    if (property === 'a') {
      return {configurable: true, enumerable: true};
    }
  }
});

const hasOwn = Object.prototype.hasOwnProperty;

console.log(hasOwn.call(p, 'a'));
console.log(hasOwn.call(p, 'b'));

Это заданное поведение, а не особенность конкретной реализации:

person Michał Perłakowski    schedule 06.11.2016

На самом деле я собирался ответить на свой вопрос сам, но я был слишком медленным, и другие ответили на него первыми (и к тому же добавили очень полезную информацию). Тем не менее, вот ответ, который я хотел написать, на случай, если это может кому-то помочь:


Похоже, что ловушка getOwnPropertyDescriptor срабатывает при вызове hasOwnProperty. Таким образом, вы можете поймать hasOwnProperty, выполнив следующие действия:

getOwnPropertyDescriptor(target, name) {
    return {
        value : target[name],
        //use a logical set of descriptors:
        enumerable : true,
        configurable : true,
        writable : true
    };
}

Другая часть также захватывает get и ownKeys:

get(target, name) {
    return {}; //replace this with a relevant object
}

//These will be iterated over as part of the for loop
ownKeys() {
    return ["RelevantProperty1", "RelevantProperty2"];
}

В общем, поскольку вы должны вернуть массив свойств при перехвате ownKeys, использование прокси, похоже, не делает ситуацию намного лучше в этом случае использования. Я думаю, что в большинстве ситуаций следующее будет работать так же хорошо и будет менее хрупким:

let obj = {};
let keys = ["a" , "b"];
for (let key of keys) {
    obj[key] = {}; //relevant object
}

Поэтому использование прокси может быть излишним.

person GregRos    schedule 06.11.2016
comment
Обычно лучше подготовить ответ до публикации вопроса, чтобы вы могли опубликовать их сразу. Спасает от подобных ситуаций. Тем не менее, полезный. - person VLAZ; 06.11.2016
comment
@vlaz это хороший момент. Я запомню это в будущем. Тем не менее, я рад, что Готдо и другие подробно рассказали, как работает этот механизм. - person GregRos; 07.11.2016