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)