Когда я сегодня почистил 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 Ван Сяоцзян.