Могу ли я делать все, что захочу, изучая Proxy? Простая интерпретация умного кода

JavaScript
Могу ли я делать все, что захочу, изучая Proxy? Простая интерпретация умного кода

Когда я сегодня почистил github, я увиделjustjavacЗдоровяк по вышел с таким куском кода(justjavac/proxy-www):

const www = new Proxy(new URL('https://www'), {
    get: function get(target, prop) {
        let o = Reflect.get(target, prop);
        if (typeof o === 'function') {
            return o.bind(target)
        }
        if (typeof prop !== 'string') {
            return o;
        }
        if (prop === 'then') {
            return Promise.prototype.then.bind(fetch(target));
        }
        target = new URL(target);
        target.hostname += `.${prop}`;
        return new Proxy(target, { get });
    }
});

На первый взгляд это может показаться немного запутанным, но это удивительно! Вы можете напрямую получить доступ к URL-адресу как к переменной:

www.baidu.com.then(response => {
    console.log(response.status);
    // ==> 200
})

использоватьasync / awaitСинтаксис становится проще:

const response = await www.baidu.com

console.log(response.ok)
// ==> true

console.log(response.status);
// ==> 200

Все это исходит из того, что было предложено в ES6.ProxyиReflectГрамматика, мы могли бы также использовать этот код, чтобы просто узнать о них~

ProxyТо есть агент. Друзьям, изучавшим компьютерные сети, наверняка знакомо это слово. В компьютерной сети прокси означает, что клиент не подключается к серверу напрямую, а передает запросы через некоторые промежуточные машины, чтобы повысить скорость доступа и безопасность.

в JavaScriptProxyЭто также аналогичная функция, за исключением того, что блокируются уже не сервер и клиент, а общие объекты и пользователи, которые используют объекты. Возьмите этот код в качестве примера,Proxyпросто зажатыйnew URL("www")и для доступа или изменения этогоURLмежду пользователями:

const www = new Proxy(new URL('https://www'), { ... }});

Добавление дополнительного уровня прокси, естественно, для выполнения некоторых пользовательских операций,ProxyОбъект будет захвачен вторым параметром, переданным в[[Get]],[[Set]]такой внутренний метод. Этот код угоняет[[Get]]:

const www = new Proxy(new URL('https://www'), {
    get: function get(target, prop) { ... }
});

заменены[[Get]]Функция имеет два параметра:targetотносится к исходному объекту, т.URL;propимя объекта, к которому нужно получить доступ, дляwww.baidu.comНапример, первый слойpropэто"baidu", второй слой"com".

Продолжая изучать этот код, мы наткнулисьReflect.Reflectда иProxyвыдвигать вместе, если это просто понимать, то поставить[[Get]],[[Set]]Такие внутренние функции преобразуются в функциональные методы вызова.Reflectчасто иProxyИспользуется в сочетании для повторного применения перехваченной операции к исходному объекту. это здесь:

let o = Reflect.get(target, prop);

Его также можно понимать как:

let o = target[prop]

Остальной код легко понять:

const www = new Proxy(new URL('https://www'), {
    get: function get(target, prop) {
        let o = Reflect.get(target, prop);
        // 当 `[[Get]]` 的属性为 `URL` 已有的函数,那么就返回这个已有的函数
        // 补:例如 www.justjavac.com.toString()
        if (typeof o === 'function') {
            return o.bind(target)
        }
        // 当 `prop` 不是字符串的时候,返回当前的属性
        // 补:object key 只能是字符串和 Symbol,所以这里是判断是否为 Symbol。
        //    使用场景是 www.justjavac.com + 'foo/bar'
        if (typeof prop !== 'string') {
            return o;
        }
        // 如果 `prop` 为 `then`,就把 `URL` 转化为 `fetch` 后的
        // `Promise`。(这样的结果就是不能调用 `www.then.com` 这样的网址了)
        if (prop === 'then') {
            return Promise.prototype.then.bind(fetch(target));
        }
        // 对于其余的情况,把新增加的字符串加进域名中,并重新包一层 `Proxy`。
        target = new URL(target);
        target.hostname += `.${prop}`;
        return new Proxy(target, { get });
    }
});

Примечание: спасибо автору области комментариев за дополнение!

На данный момент вы понимаете этот фрагмент кода? это правильно?ProxyиReflectЕсть базовое понимание использования? Если вы хотите понять их глубже, я рекомендую эту статью объемом 10 000 слов:Прокси и отражение by Ван Сяоцзян.