使用JavaScript的Proxy监听对象属性变化并进行类public/private的访问控制


发布者 ourjs  发布时间 1559991024343
关键字 JS学习  JavaScript 
Proxy是ES6的引入的一个对象监听机制。可视为JavaScript对象的一个代理中间件。用户在访问对象时,会触发自定义行为。

监听属性变化

Proxy最简单的用法是可以监听对象属性的变化,比如下面的,当 obj 的 visit 属性改变时,自动更新页面上相应的 input元素值。

<form>
  <input type="text" name="visit">
</form>

<script type="text/javascript">
var obj = {}

var handler = {
  set: function(target, name, value) {    
    //改变被代理对象的值,使之保持一致
    target[name] = value

    var input = document.querySelector('[name=' + name + ']')
    if (input) {
      input.value = value
    }
  }
}

var proxy = new Proxy(obj, handler);
proxy.visit = 100

setInterval(function() {
  proxy.visit++
}, 1000)
</script>
上例每秒都会更新表单中对应属性输入框的值。

Proxy还可以用来检查设置的值是否规范:

var obj = {}

var handler = {
  set: function(target, name, value) {    
    if (isNaN(Number(value))) {
      throw 'Type error'
    }

    target[name] = value
  }
}

var proxy = new Proxy(obj, handler);
执行结果,obj中所有对象只允许赋值数字:
proxy.visit = 'OurJS'
> Uncaught Type error

proxy.visit = 100
> 100

用Proxy实现private/ public

ES6已经有了关于实现private修饰符的提案,但是浏览器目前还没有实施,示例代码如下:

class Something {
  #property;

  constructor(){
    this.#property = "test";
  }
}

const instance = new Something();
console.log(instance.property); //=> undefined
这个提案的缺陷很明显,private私有属性必须以'#'开头的方式命名。用Proxy就可以简单实现这个方案:

var obj = { '#user': 'OurJS' }
var proxy = new Proxy(obj, {
  get: function(target, name) {
    if (name[0]=='#') {
      throw 'Access forbidden'
    }
  }
});
执行结果:
console.log(proxy['#user'])
> Uncaught Access forbidden

因为Proxy也是可以继承的,这样只需提供相应的Proxy对象即可实现public/ private、set/get控制等强控制类型的类。

有一些框架,比如vue3.0即准备利用Proxy对象,实现Model到View的自动渲染。

控制 in 语法

Proxy可以控制in语法
var obj = { _visit: 100, name: 'OurJS' }

var proxy = new Proxy(obj, {
  has: function(target, name) {
    return name[0] != '_'
  }
})
使用
_visit in proxy
> VM306:1 Uncaught ReferenceError: _visit is not defined
name in proxy
true

Proxy也提供其他语法代理控制,类似的可以控制for in枚举等,可参考:

Proxy/ Proxy.revocable
handler.apply
handler.construct
handler.defineProperty
handler.deleteProperty
handler.enumerate(Deprecated)
handler.get
handler.getOwnPropertyDescriptor
handler.getPrototypeOf
handler.has
handler.isExtensible
handler.ownKeys
handler.preventExtensions
handler.set
handler.setPrototypeOf





回复 (1)
微信扫码 立即评论




 热门文章 - 分享最多
  1. Node.JS中用concat和push连接两个或多个数组的性能比较
  2. jQuery用$.prop,$.attr方法来获取或设置checkbox当前选中状态
  3. JavaScript中将字符串true或false转换成Boolean类型
  4. 判断是否为对象typeof abc == 'object' 与 instanceof 性能比较
  5. 用网页table thead tfoot元素完美控制页眉页脚显示内容打印的简单方式
  6. jQuery用outterHtml获取相对innerHTML父一级包含其自身的html代码内容
  7. 微服务运维难维护?数据基础架构公司Segment宣布放弃微服务构架
  8. Node.JS在命令行中检查Chrome浏览器是否安装,并打开指定网址
  9. Node.JS用RSA签名算法公钥加密私钥解密,实现License软件授权验证
  10. Node.JS借助OS模块获取当前Windows系统用户登录名

 相关阅读
  1. JavaScript求一个字符串的字节长度
  2. Node.JS用RSA签名算法公钥加密私钥解密,实现License软件授权验证
  3. Node.JS借助OS模块获取当前Windows系统用户登录名
  4. JavaScript中将字符串true或false转换成Boolean类型
  5. jQuery用$.prop,$.attr方法来获取或设置checkbox当前选中状态
  6. Node.JS中用concat和push连接两个或多个数组的性能比较
  7. 判断是否为对象typeof abc == 'object' 与 instanceof 性能比较
  8. 配置TinyMCE网页文本编辑器不显示html head body等标签信息
  9. node.js中将console.log日志内容输出到文件
  10. typeof判断参数是否为undefined与全等判断法性能比较

  开源的 OurJS
OurJS开源博客已经迁移到 OnceOA 平台。

  关注我们
扫一扫即可关注我们:
OnceJS

OnceOA