ES6 Proxy代理

一、代理

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。

二、常用拦截方法

在这里插入图片描述
在这里插入图片描述

// ES5
let obj = {}
let newVal = ''
Object.defineProperty(obj, 'name', {
  get () {
    console.log('get')
    return newVal
  },
  set (val) {
    console.log('set')
    newVal = val
  }
})
obj.name = 'zz'
console.log(obj.name )

// ES6 proxy
let obj = {}
let p = new Proxy(obj, {})
p.name = 'zzzzz'
console.log(p, obj.name)

// get
let arr = [11,22,33]
arr = new Proxy(arr, {
  get(target, key) {
    console.log(target, key)
    if (key in target) {
      return target[key]
    } else {
      return 'err'
    }
  }
})
console.log(arr[5])

// set
let arr = []
arr = new Proxy(arr, {
  set(target, key, val) {
    if (typeof val === 'number') {
      target[key] = val
      return true
    } else {
      return false
    }
  }
})
arr.push(1)
console.log(arr, arr[0], arr[1])

// has
let range = {
  min: 1,
  max: 5
}
range = new Proxy(range, {
  has(target, key) {
    return key >= target.min && key <= target.max
  }
})
console.log( 2 in range)
console.log( 6 in range)

// ownKeys
let obj = {
  name: 'zz',
  [Symbol('66')]: 66
}
Object.getOwnPropertyNames(obj)
Object.getOwnPropertySymbols(obj)
Object.keys(obj)
Reflect.ownKeys(obj)
let userInfo = {
  name: 'zz',
  age: 25,
  _password: '123456'
}
userInfo = new Proxy(userInfo, {
  ownKeys(target) {
    return Object.keys(target).filter(key => !key.startsWith('_'))
  }
})
for (let key in userInfo) {
  console.log(key)
}
console.log(Object.keys(userInfo))

// apply
let sum = (...args) => {
  let sum = 0
  args.forEach(item => {
    sum += item
  })
  return sum
}
sum = new Proxy(sum, {
  apply(target, ctx, args) {
    return target(...args) * 2
  }
})
console.log(sum(1,2))
console.log(sum.call(null, 1,2,3));

// construct
let User = class {
  constructor (name) {
    this.name = name
  }
}
User = new Proxy(User, {
  construct(target, args, newTarger) {
    return new target(...args)
  }
})
console.log(new User('zzz'))

// 
let user = {
  name: 'zz',
  age: 25,
  _password: '123456'
}

user = new Proxy(user, {
  get(target, key) {
    if (key.startsWith('_')) {
      throw new Error('不可访问')
    } else {
      return target[key]
    }
  },
  set(target, key, val) {
    if (key.startsWith('_')) {
      throw new Error('不可访问')
    } else {
      target[key] = val
      return true
    }
  },
  deleteProperty(target, key) {
    if (key.startsWith('_')) {
      throw new Error('不可删除')
    } else {
      delete target[key]
      return true
    }
  },
  ownKeys(target) {
    return Object.keys(target).filter(key => !key.startsWith('_'))
  },
  // apply
})
try {
  console.log(user._password)
} catch(e) {
  console.log(e.message)
}
console.log(user.name)
user.age = 18
console.log(user)
for (let key in user) {
  console.log(key)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老电影故事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值