TS 进阶用法 proxy & Reflect(TS-23)

proxy:对象代理(是ES6新增的对象拦截器,能够监听到一个对象的变化)

Reflect:配合proxy来操作对象

Proxy

Proxy 对象用于创建一个对象的代理,从而实现基本操作的拦截和自定义(如属性查找、赋值、枚举、函数调用等)

target

要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

handler

一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

handler.get()本次使用的 get

属性读取操作的捕捉器。

handler.set()本次使用的 set

属性设置操作的捕捉器。

Reflect

与大多数全局对象不同 Reflect 并非一个构造函数,所以不能通过 new 运算符对其进行调用,或者将 Reflect 对象作为一个函数来调用。Reflect 的所有属性和方法都是静态的(就像 Math 对象)

Reflect.get(target, name, receiver)

Reflect.get 方法查找并返回 target 对象的 name 属性,如果没有该属性返回 undefined

Reflect.set(target, name,value, receiver)

Reflect.set 方法设置 target 对象的 name 属性等于 value

type Person = {
	name:string,
	age:number,
	text:string
}

const proxy = (object:any,key:any)=>{//我们要自己实现proxy啦
    return new Proxy(object,{
        get(target,prop,receiver){
            console.log('================>get',prop);
            //prop就是一个key,target就是地下那个man的对象,receiver是跟target一样的值,防止上下文错误的
            return Reflect.get(target,prop,receiver)//这里刚好对应的也是这三个参数
        },
        set(target,prop,value,receiver){//多了一个value,因为我们要设置值
        //日志
        	console.log('================>set',prop);
        	return Reflect.set(target,prop,value,receiver)
    	}
    })
}

//日志监听函数
//由于我们要监听man里面的内容,所以这里可以使用联合类型
const logAccess = <T>(object: T ,key:"name" | "age" | "text"):T =>{//为了使其灵活度高一点,我们不使其object等于Person,而是为泛型T,使用的时候再去设置
    return proxy(object,key)
}

let man:Person = ({
    name:"小满",
    age:22,
    text:"三秒真男人"
})

let man2 = logAccess({
    name:"小余"
},'name')

man.age = 30//走set
man.age//走get
console.log(man)

泛型优化

const logAccess = <T>(object: T ,key:keyof T):T =>{//为了使其灵活度高一点,我们不使其object等于Person,而是为泛型T,使用的时候再去设置。key也不固定死,而是使用keyof,将我们传入的对象推断为联合类型
    return proxy(object,key)
}

let man2 = logAccess({
    name:"小余",
    id:925
},'id')//就可以动态的去约束类型

let man2 = logAccess({
    name:"小余",
    id:925
},'id2')//报错,因为我们类型里没有id2

优化完整版

type Person = {
    name: string,
    age: number,
    text: string
}
 
 
const proxy = (object: any, key: any) => {
    return new Proxy(object, {
        get(target, prop, receiver) {
            console.log(`get key======>${key}`);
            return Reflect.get(target, prop, receiver)
        },
 
        set(target, prop, value, receiver) {
            console.log(`set key======>${key}`);
 
            return Reflect.set(target, prop, value, receiver)
        }
    })
}
 
 
const logAccess = <T>(object: T, key: keyof T): T => {
    return proxy(object, key)
}
 
let man: Person = logAccess({
    name: "小满",
    age: 20,
    text: "我的很小"
}, 'age')
 
 
let man2 = logAccess({
    id:1,
    name:"小满2"
}, 'name')
 
man.age = 30
 
console.log(man);
&lt;think&gt;嗯,用户想了解TypeScript的内置对象列表,并且提到了官方文档。首先,我需要回忆一下TypeScript的内置对象主要分为哪几类。根据之前学过的知识,TypeScript的内置对象通常包括ECMAScript标准的内置对象,比如Boolean、Number、String这些基本包装类型,还有Date、RegExp、Error等。另外,浏览器环境下的BOM和DOM对象,比如Window、Document、HTMLElement这些也应该算在内。不过用户可能更关注的是ECMAScript部分,因为BOM和DOM是Web API的一部分,可能根据运行环境不同有所变化。 然后,我需要确认官方文档中的相关内容。TypeScript官方文档应该会在Basic Types或者Advanced Types部分提到内置对象。比如,像Boolean、Number、String这些在TypeScript中可以作为类型直接使用。还有Array、Function、Object这些内置构造函数对应的类型。另外,ES6引入的Promise、Map、Set等结构也应该包含在内置对象中。 用户可能希望得到一个分类清晰的列表,所以需要分门别类地整理。比如分为基本对象、集合对象、错误对象、数学和日期对象等。同时,还需要注意一些特殊的类型,比如迭代器相关的Iterable、Generator,或者ES2015之后新增的ProxyReflect等。不过这些可能属于更高级的内置对象,需要根据文档确认是否包含在内。 另外,用户提到的引用中有提到内置工具类型,但这里的问题是关于内置对象,所以可能需要区分开。内置对象是指JavaScript中原本存在的对象,而工具类型是TypeScript提供的类型操作,比如Partial、Pick等,这可能是另一个话题。不过用户的问题明确提到内置对象,所以应该专注于那些可以在TypeScript中直接使用的JavaScript内置对象。 可能还需要举例说明如何使用这些内置对象作为类型,比如声明一个数组可以用Array&lt;number&gt;或者number[],日期对象用Date类型。此外,像JSON对象、Math对象这些全局单体内置对象也需要提及,虽然它们可能没有对应的类型构造函数,但在TypeScript中可以直接使用它们的类型,比如JSON.parse返回any类型,但可以显式指定。 还需要注意,TypeScript在处理内置对象时,会根据lib配置来包含不同的环境声明,比如ES5、ES6等,这可能影响内置对象的可用性。但用户的问题可能更关注默认情况下的内置对象列表,所以可能需要提到常见的那些,并建议查阅官方文档的对应章节。 最后,需要确保提供的列表准确,最好参考官方文档的结构。比如,在TypeScript文档中,内置对象通常列在&ldquo;lib&rdquo;库文件中,每个对应的ES版本有不同的声明文件。用户可能需要知道如何根据target配置来访问不同版本的内置对象。 总结来说,回答应该分点列出ECMAScript内置对象、BOM/DOM对象,并给出每个类别下的具体对象示例,同时说明它们在TypeScript中的使用方式,比如作为类型注解。此外,提供官方文档链接供用户进一步查阅,但需要确认最新的文档链接是否正确,避免过时信息。&lt;/think&gt;### TypeScript内置对象分类及官方文档说明 TypeScript内置对象主要分为以下两类: --- #### 一、ECMAScript 标准内置对象 这些对象是JavaScript语言规范定义的核心内容,在TypeScript中可以直接作为类型使用: 1. **基本包装类型** - $Boolean$:布尔值类型 - $Number$:数字类型 - $String$:字符串类型 - $Symbol$(ES6+):唯一标识符类型[^1] 2. **集合与数据结构** - $Array&lt;T&gt;$ 或 $T[]$:数组类型 - $Map&lt;K,V&gt;$(ES6+):键值对集合 - $Set&lt;T&gt;$(ES6+):唯一值集合 - $Promise&lt;T&gt;$(ES6+):异步操作容器[^3] 3. **错误处理** - $Error$:基础错误类型 - $RangeError$、$SyntaxError$等:特定错误类型 4. **数学与日期** - $Math$:数学工具对象(静态方法) - $Date$:日期时间类型 5. **其他核心对象** - $Object$:所有对象的基类 - $Function$:函数类型 - $RegExp$:正则表达式类型 - $JSON$:JSON数据处理对象 --- #### 二、浏览器环境对象 (BOM/DOM) 这类对象仅在浏览器环境中有效,通过`lib: [&quot;dom&quot;]`配置启用[^4]: 1. **DOM元素类型** - $HTMLElement$:所有HTML元素的基类 - $Document$:文档对象 - $Window$:浏览器窗口对象 2. **事件对象** - $Event$:基础事件类型 - $MouseEvent$、$KeyboardEvent$等:具体事件类型 --- #### 官方文档位置 1. **内置对象列表**:在TypeScript文档的[Basic Types](https://www.typescriptlang.org/docs/handbook/basic-types.html)和[ECMAScript Standard Built-in Objects](https://github.com/microsoft/TypeScript/blob/main/src/lib/es5.d.ts)章节中查看完整列表 2. **DOM类型声明**:参考[TypeScript DOM库定义文件](https://github.com/microsoft/TypeScript/blob/main/lib/lib.dom.d.ts) --- ### 使用示例 ```typescript // ECMAScript内置对象使用 const date: Date = new Date(); const regex: RegExp = /test/gi; // DOM对象类型标注 const button: HTMLButtonElement = document.querySelector(&quot;button&quot;)!; button.addEventListener(&quot;click&quot;, (e: MouseEvent) =&gt; { /*...*/ }); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值