todo

常见的基于数据劫持的双向绑定有两种实现,一个是目前Vue在用的Object.defineProperty,另一个是ES2015中新增的Proxy,而Vue的作者宣称将在Vue3.0版本后加入Proxy从而代替Object.defineProperty,本文详细解析了es6中的Proxy方法,严格来讲Proxy应该被称为『代理』而非『劫持』。

Proxy

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

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

var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`getting ${key}!`);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console.log(`setting ${key}!`);
return Reflect.set(target, key, value, receiver);
}
});

上面代码对一个空对象架设了一层拦截,重定义了属性的读取(get)和设置(set)行为。这里暂时先不解释具体的语法,只看运行结果。对设置了拦截行为的对象obj,去读写它的属性,就会得到下面的结果。

obj.count = 1
// setting count!
++obj.count
// getting count!
// setting count!
//

上面代码说明,Proxy 实际上重载(overload)了点运算符,即用自己的定义覆盖了语言的原始定义。

ES6 原生提供 Proxy 构造函数,用来生成 Proxy 实例。

var proxy = new Proxy(target, handler);

Proxy 对象的所有用法,都是上面这种形式,不同的只是handler参数的写法。其中,new Proxy()表示生成一个Proxy实例,target参数表示所要拦截的目标对象handler参数也是一个对象,用来定制拦截行为。

下面是另一个拦截读取属性行为的例子。

var proxy = new Proxy({}, {
get: function(target, property) {
return 35;
}
}); proxy.time //
proxy.name //
proxy.title //

上面代码中,作为构造函数,Proxy接受两个参数。第一个参数是所要代理的目标对象(上例是一个空对象),即如果没有Proxy的介入,操作原来要访问的就是这个对象;第二个参数是一个配置对象,对于每一个被代理的操作,需要提供一个对应的处理函数,该函数将拦截对应的操作。比如,上面代码中,配置对象有一个get方法,用来拦截对目标对象属性的访问请求。get方法的两个参数分别是目标对象所要访问的属性。可以看到,由于拦截函数总是返回35,所以访问任何属性都得到35

注意,要使得Proxy起作用,必须针对Proxy实例(上例是proxy对象)进行操作,而不是针对目标对象(上例是空对象)进行操作。

如果handler没有设置任何拦截,那就等同于直接通向原对象。

var target = {};
var handler = {};
var proxy = new Proxy(target, handler);
proxy.a = 'b';
target.a // "b"

上面代码中,handler是一个空对象,没有任何拦截效果,访问proxy就等同于访问target

一个技巧是将 Proxy 对象,设置到object.proxy属性,从而可以在object对象上调用。

var object = { proxy: new Proxy(target, handler) };

Proxy 实例也可以作为其他对象的原型对象。

var proxy = new Proxy({}, {
get: function(target, property) {
return 35;
}
}); let obj = Object.create(proxy);
obj.time //

上面代码中,proxy对象是obj对象的原型obj对象本身并没有time属性,所以根据原型链,会proxy对象上读取该属性,导致被拦截。

同一个拦截器函数,可以设置拦截多个操作。

Proxy-代理器(预计vue3.0实现双向绑定的方式)的更多相关文章

  1. ES6新特性:Proxy代理器

    ES6新特性:Proxy: 要使用的话, 直接在浏览器中执行即可, node和babel目前还没有Proxy的polyfill;,要使用的话,直接在浏览器中运行就好了, 浏览器的兼容性为:chrome ...

  2. Vue2.0实现双向绑定的原理

    一.几种实现双向绑定的做法 目前几种主流的mvc(vm)框架都实现了单向数据绑定,而我所理解的双向数据绑定无非就是在单向绑定的基础上给可输入元素(input.textare等)添加了change(in ...

  3. Vue2.0 Props双向绑定报错简易处理办法

    在写项目的时候遇到了一个报错问题,虽然功能是正常运行,chrome的提示是:[Vue warn]: Avoid mutating a prop directly since the value wil ...

  4. 双向绑定Proxy VS Object.defineProperty

    Vue3.0的双向绑定将使用Proxy代替Object.defineProperty,据尤大说,速度提升了1倍. 本文我们来探讨一下Proxy对比Object.defineProperty究竟有哪些优 ...

  5. 深入理解Proxy 及 使用Proxy实现vue数据双向绑定

    阅读目录 1.什么是Proxy?它的作用是? 2.get(target, propKey, receiver) 3.set(target, propKey, value, receiver) 4.ha ...

  6. vue2.0 双向绑定原理分析及简单实现

    Vue用了有一段时间了,每当有人问到Vue双向绑定是怎么回事的时候,总是不能给大家解释的很清楚,正好最近有时间把它梳理一下,让自己理解的更清楚,下次有人问我的时候,可以侃侃而谈. 一.首先介绍Obje ...

  7. 前端面试题整理——VUE双向绑定原理

    VUE2.0和3.0数据双向绑定的原理,并说出其区别. 代码: <!DOCTYPE html> <html lang="en"> <head> ...

  8. 探讨vue的双向绑定原理及实现

    1.vue的实现原理 vue的双向绑定是由数据劫持结合发布者-订阅者模式实现的,那么什么是数据劫持?vue是如何进行数据劫持的?说白了就是通过Object.defineProperty()来劫持对象属 ...

  9. vue3.0中的双向数据绑定方法

    熟悉vue的人都知道在vue2.x之前都是使用object.defineProperty来实现双向数据绑定的 而在vue3.0中这个方法被取代了 1. 为什么要替换Object.definePrope ...

随机推荐

  1. [gym101981M][2018ICPC南京M题]Mediocre String Problem

    题目链接 题目大意是问在$S$串中找区间$[i,j]$,在$T$串中找位置$k$,使得$S[i,j]$和$T[1,k]$可以组成回文串,并且$j-i+1>k$,求这样的三元组$(i,j,k)$的 ...

  2. mysql文本后面带换行符导致查询不到

    UPDATE tablename SET  FIELD = REPLACE(REPLACE(FIELD, CHAR(10), ''), CHAR(13), ''); CHAR(10):  换行符 CH ...

  3. hdu2444The Accomodation of Students (最大匹配+判断是否为二分图)

    题意 首先判断所有的人可不可以分成两部分,每部分内的所有人都相互不认识.如果可以分成 则求两部分最多相互认识的对数. 解题 类似分成两组,同组互不相关,就可能使判断是否为二分图 能否分成两部分 则是判 ...

  4. javascript高级程序设计读书笔记-事件(一)

    读书笔记,写的很乱   事件处理程序   事件处理程序分为三种: 1.html事件2. DOM0级,3,DOM2级别  没有DOM1 同样的事件 DOM0会顶掉html事件   因为他们都是属性  而 ...

  5. 在 Chrome DevTools 中调试 JavaScript 入门

    第 1 步:重现错误 找到一系列可一致重现错误的操作始终是调试的第一步. 点击 Open Demo. 演示页面随即在新标签中打开. OPEN DEMO 在 Number 1 文本框中输入 5. 在 N ...

  6. C# 并行编程之早起三件事

    故事背景 透着纱的窗外的阳光, 又是一个星期一. 慢慢来 一看时间, 还早, 那么蹦跶起来 穿衣 刷牙 洗脸 用代码来说的话, 应该是这样: // Program.cs using System; u ...

  7. wex5 sqllite本地数据库的运用

    http://doc.wex5.com/?p=3774 需要引入包require("cordova!com.brodysoft.sqlitePlugin"); //本地数据库操作 ...

  8. 启动angular项目,端口被占用

    启动项目,npm start,报如下错误: 解决:1.win+R,输入CMD,启动命令行窗口. 2.输入netstat -ano或者netstat -ano|findstr 8080,查看8080端口 ...

  9. Ubuntu18.04 安装netstat

    关键命令 sudo apt-get install net-tools 参考博客:https://www.cnblogs.com/2sheep2simple/p/10611650.html

  10. Qualcomm_Mobile_OpenCL.pdf 翻译-5-性能优化的概述

    这章提供了一个OpenCL应用程序优化的总体概述.更多的细节将会在接下来的章节中找到. 注意:OpenCL程序的优化是具有挑战性的.相比初始的程序开发工作,经常需要做更多的工作. 5.1 性能移植性 ...