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 });
}
});
// 访问百度
www.baidu.com.then(response => {
console.log(response.status);
// ==> 200
})
解析
- property key 只有 2 种:string 和 symbol,其实直接判断是否为 symbol 就行了。ts 为了方便,定义了 3 种(额外定义了一个 number),其实 js 只有 2 种。
- 第一个判断 Reflect.get(target, prop) 是否为 function,是为了调用函数,例如
www.baidu.com.toString
() === "
https://www.baidu.com/
"
- 第二个判断是否了调用 URL 对象内置的 symbol,比如
www.baidu.com
+ 'a/b/c' === "
https://www.baidu.com/a/b/c
"
- www.baidu:www 是对象,点(.)是访问 www 对象的 ‘baidu’ 属性,因为 www 对象没有 ‘baidu’ 属性,因此进入 proxy 的 get 逻辑
- 返回了另一个 proxy,其中的 url 是 www.baidu,当继续调用 .com 方法时,继续上面的步骤。直到调用了 .then 后,运行 fetch(target)