《深入理解ES6》读书笔记(4) -- proxy、reflect和双向绑定

proxy、reflect

Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。

var proxy = new Proxy(target, handler);

其中target, handler其实都是对象,target为目标、要代理的对象,handler定义了一堆代理的方法。

proxy内置13个方法,与Reflect方法对应。

方法proxyreflect
get();拦截读取操作(target,name,receiver)查找并返回target的name属性
set();拦截赋值操作(target,name,value, receiver)
apply();拦截函数的调用、call 和 apply 操作Reflect.apply(Math.min, Math, age) === Math.min.apply(Math, age)
has();可以拦截hasProperty的操作,返回一个布尔值。对in方法生效,对for in不生效。(obj,name) Reflect.has(obj,name) => true
construct();// 拦截new命令,必须返回对象,否则报错。new Greet(‘落白’) === Reflect.construct(Greet, [‘落白’])
deleteProperty();拦截delete操作。 configrable的属性不能被此方法输出,否则报错。(obj, ‘name’)删除成功或属性不存在则返回true
defineProperty();拦截defineProperty方法。Object.defineProperty() === Reflect.defineProperty()
getOwnPropertyDescriptor();拦截Object.getOwnPropertyDescriptor();===
getPrototypeOf();拦截对象原型。let myobj = new Fancy(); Object.getPrototypeOf(myobj) === Reflect.getPrototypeOf(myObj) === Fancy.prototype();
isExtensible();拦截Object.isExtensible();返回布尔值,表对象是否可拓展
ownKeys();拦截对象自身属性的读取(Object.keys()..返回对线的所有属性
preventExtensions();拦截Object.preventExtensions()使对象不可扩展
setPrototypeOf();拦截Object.setPrototypeOf();(obj,newProto)

proxy.revocable用于取消Proxy实例。
目标对象的this会指向Proxy代理。

definePropety

语法
Object.defineProperty(obj, prop, descriptor)

obj: 要在其上定义属性的对象。

prop: 要定义或修改的属性的名称。

descriptor: 将被定义或修改的属性的描述符。

  1. configurable 可配置、删除
  2. enumerable 可枚举
    数据描述符:
  3. value 该属性对应的值
  4. writable 可读写
    存取描述符:
  5. get: 提供 getter 的方法,默认为 undefined
  6. set: 提供 setter 的方法, 默认为 undefined

** 属性描述符必须是数据描述符或者存取描述符两种形式之一,不能同时是两者。

实现简单的双向绑定

数据驱动dom,即当数据改变的时候,自动进行渲染工作。举个例子:
HTML 中有个 span 标签和 button 标签

1
2
<span id="container">1</span>
<button id="button">点击加 1</button>

 

当点击按钮的时候,span 标签里的值加 1。

1
2
3
4
document.querySelector('#button').addEventListener("click", function(){
    var container = document.querySelector("#container");
    container.innerHTML = Number(container.innerHTML) + 1;
});

defineProperty方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var obj = {
    value: 1
}

// 储存 obj.value 的值
var value = 1;

Object.defineProperty(obj, "value", {
    get: function() {
        return value;
    },
    set: function(newValue) {
        value = newValue;
        document.getElementById('container').innerHTML = newValue;
    }
});

document.getElementById('button').addEventListener("click", function() {
    obj.value += 1;
});

 

proxy实现

var obj = {
  value: 1
}

// 储存 obj.value 的值
var value = 1;

var proxy = new Proxy(obj, {
  get: (target, key) => value,
  set: (target, key, newValue) => {
    value = newValue;
    document.getElementById('container').innerHTML = newValue;
  }
})

document.getElementById('button').addEventListener("click", function () {
  proxy.value += 1;
});

参考资料:
《ES6标准入门》
ES6 系列之 defineProperty 与 proxy

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值