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'))
总结

 
                    
                
                
            
        
浙公网安备 33010602011771号