proxy代理

// proxy [ˈprɑːksi] 代理
// // es5代理方式
// let obj = {}
// let newVal = ''
// Object.defineProperty(obj, 'name', { // 第一个变量名称当前对象 第二个为当前对象的属性值
// get() { // 第三个是一个对象在里面写一些拦截的方法
// return newVal
// },
// set(val) {
// console.log('set')
// newVal = val
// }
// })
// obj.name = 'es'
// console.log(obj.name) // => get imooc

//proxy
// let obj = {}
// let p = new Proxy(obj, {})
// p.name = 'hky'
// console.log(obj.name)
// for (let key in obj) {
// console.log(key, obj[key])
// }

// get 获取钩子函数 (拦截函数)
// let arr = [7, 8, 9]
// arr = new Proxy(arr, {
// get(target, prop) { // 对应2个参数 第一个当前处理的对象 第二个 传递的参数
// // console.log(target, prop)
// return prop in target ? target[prop] : 'error'
// }
// })
// console.log(arr[1]) // => 8
// console.log(arr[10]) // => error

// dictionary
// let dict = {
// 'hello': '你好',
// 'world': '世界'
// }
// dict = new Proxy(dict, {
// get(target, prop) {
// return prop in target ? target[prop] : prop
// }
// })

// console.log(dict['world']) // => 世界
// console.log(dict['world']) // =>

// set 设置
// let arr = []
// arr = new Proxy(arr, {
// set(target, prop, val) { // 第一个参数当前目标对象 第二个设置属性值 第三个是要设置的值
// if (typeof val === 'number') {
// target[prop] = val
// return true
// } else {
// return false
// }
// }
// })
// arr.push(5)
// arr.push(6)
// console.log(arr[0], arr[1], arr.length) // 5, 6, 2
// Proxy 代理一个对象的时候并不会破坏原有的东西

// has 判断当前key是否在对象里面 返回布尔值
// let range = {
// start: 1,
// end: 5
// }
// range = new Proxy(range, {
// has(target, prop) {
// return prop >= target.start && prop <= target.end
// }
// })
// console.log(2 in range) // => true
// console.log(9 in range)// => false

//ownKeys 用于当前对象的循环遍历 进行拦截操作的
// let obj = {
// name: 'imooc',
// [Symbol('es')]: 'es6'
// }
// console.log(Object.getOwnPropertyNames(obj)) // => 只有 name
// console.log(Object.getOwnPropertySymbols(obj)) // => 只有 Symbol
// console.log(Object.keys(obj)) // => 只有 name
// for (let key in obj) {
// console.log(key, obj[key])
// }
// let userInfo = {
// name: 'hky',
// age: 27,
// _password: '***'
// }
// userInfo = new Proxy(userInfo, {
// ownKeys(target) {
// return Object.keys(target).filter(key => !key.startsWith('_')) // 判断是否以下划线为开头
// }
// })
// // for(let key in userInfo) { // name age
// // console.log(key);
// // }
// // console.log(Object.keys(userInfo))
// let user = {
// name: 'hky',
// age: 27,
// _password: '***'
// }
// user = new Proxy(user, {
// get(target, prop) {
// if (prop.startsWith('_')) {
// throw new Error('不可访问')
// } else {
// return target[prop]
// }
// },
// set(target, prop, val) {
// if (prop.startsWith('_')) {
// throw new Error('不可访问')
// } else {
// target[prop] = val
// return true
// }
// },
// deleteProperty(target, prop) { // 对删除操作进行拦截 需要返回布尔值 prop属性
// if (prop.startsWith('_')) {
// throw new Error('不可删除')
// } else {
// delete target[prop]
// return true
// }
// },
// ownKeys(target) {
// return Object.keys(target).filter(key => !key.startsWith('_'))
// }
// })
// console.log(user.age) // => 27
// console.log(user._password) // =>不可访问
// user.age = 18
// console.log(user.age)
// try {
// user._password = 'xxx'
// } catch(e) {
// console.log(e.message) // => 不可访问
// }
// try {
// // delete user.age
// delete user._password
// } catch(e) {
// console.log(e.message) // => 不可删除
// }
// for (let key in user) {
// console.log(key) // => name age 没有显示
// }

// apply 拦截函数调用 以及 call 和 apply的操作
// let sum = (...args) => {
// let num = 0
// args.forEach(item => {
// num += item
// })
// return num
// }
// sum = new Proxy(sum, {
// apply(target, ctx, val) { // 第一个参数为拦截目标 第二个参数为当前上下文 第三个参数是目标参数数组
// return target(...val) * 2
// }
// })
// // console.log(sum(1, 2, 3)) // => 12
// // console.log(sum.call(null, 1, 2)) // => 6 call 第一个参数是this指向 第二个是传递到里面的一个个参数
// console.log(sum.apply(null, [1, 2])) // call 与 apply 的区别是 call的参数是一个个传入 appl是数租

// construct /kənˈstrʌkt/ 建造        拦截new命令
let User = class { // 定义好一个类
constructor(name) {
this.name = name
}
}
User = new Proxy(User, { // construct 拦截 必须返回一个对象
construct(target, args, newTarget) { // 1当前目标对象 2当前构造函数参数列表 3 创建实例时new命令作用的构造函数
console.log('construct') // => 输出construct 说明对new 操作进行了拦截
return new target(...args)
}
})
console.log(new User('imooc'))

                         总结

 

 

 

 

 

posted @ 2021-03-08 17:41  贺可英  阅读(424)  评论(0)    收藏  举报