ES6入门系列 ----- 使用Proxy 实现观察者模式

    观察者模式是指函数自动观察数据对象的变化, 一旦对象有变化,函数就会自动执行。

它定义了一种一对多的依赖关系,我们用Proxy来实现一个简单的观察者模式(PS: 初学我们认为

观察者模式 == 发布订阅模式, 其实它们有点不同)。

    例子:

const callbacks = new Set();const observe = fn => callbacks.add(fn);const observable = obj => new Proxy(obj, {set});

function set (target, key, value, receiver) {    const result = Reflect.set(target, key, value, receiver);    callbacks.forEach(observe => observe());    return result;}//  一个可观察的对象const person = observable({name: ‘liu‘, age: 18});

function change() {    console.log(`${person.name} is ${person.age}`);}

observe(change);

person.age = 19;
  1. 首先定义了一个observe 用来存储 要触发的函数。
  2. 然后定义了一个observable 函数 对  对象的设值做了一层代理,拦截赋值操作, Reflect.set用来完成默认的设值行为, 然后触发函数。
  3. 每当对象调用对象内部的的set方法时,就会遍历触发我们添加进callbacks里的回调函数。

打印结果:当age发生变化时:打印出

 

    这样我们就简单的实现了一个观察者模式。

原文地址:https://www.cnblogs.com/LHLVS/p/11039245.html

时间: 2024-07-28 17:38:30

ES6入门系列 ----- 使用Proxy 实现观察者模式的相关文章

ES6入门系列三(特性总览下)

0.导言 最近从coffee切换到js,代码量一下子变大了不少,也多了些许陌生感.为了在JS代码中,更合理的使用ES6的新特性,特在此对ES6的特性做一个简单的总览. 1.模块(Module) --Chrome测试不可用 在ES6中,有class的概念,不过这只是语法糖,并没有解决模块化问题.Module功能则是为了解决模块化问题而提出的. 我们可以使用如下方式定义模块: 11_lib.js文件内容 // 导出属性和方法 export var PI = 3.1415926; export fun

ES6 入门系列 - 函数的扩展

1函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', '') // Hello World 上面代码检查函数log的参数y有没有赋值,如果没有,则指定默认值为World.这种写法的

ES6入门系列四(测试题分析)

0.导言 ES6中新增了不少的新特性,来点测试题热热身.具体题目来源请看:http://perfectionkills.com/javascript-quiz-es6/. 以下将一题一题来解析what和why. 1.题目一 (function(x, f = () => x) { var x; var y = x; x = 2; return [x, y, f()]; })(1) A. [2, 1, 1] B. [2, undefined, 1] C. [2, 1, 2] D. [2, undef

ES6入门系列一(基础)

1.let命令 Tips: 块级作用域(只在当前块中有效) 不会变量提升(必须先申明在使用) 让变量独占该块,不再受外部影响 不允许重复声明 总之:let更像我们熟知的静态语言的的变量声明指令 ES6新增了let命令,用来声明变量.用法类似于var,但所声明的变量,只能在let命令所在的代码块内有效. let声明的变量只有块级作用域 'use strict' { let a = 1; } console.log(a); //结果是什么? 看一段熟悉的代码: var a = []; for (va

ES6入门系列二(数值的扩展)

ES6 在 Number对象上新增了很多方法 1 .    Number.isFinite()判断是否为有限的数字 和全局的isFinite() 方法的区别是 isFinite('1') === true    ;    Number.isFinite('1') === false 全局的isFinite()先调用Number() 方法  把  变量 转化为数字再进行判断, 所以返回 true, Number.isFinite()只能判断数字, 对于非数字一律返回false 2  ,  Numb

[渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序读取相关数据

这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第六篇:为ASP.NET MVC应用程序读取相关数据 原文:Reading Related Data with the Entity Framework in an ASP.NET MVC Application 译文版权所有,谢绝全文转载--但您可以在您的网站上添加到该教程的链接. 在之前的教程中您已经完成了学校数据模型.在本教程中你将

[渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序使用高级功能

这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第十二篇:为ASP.NET MVC应用程序使用高级功能 原文:Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application 译文版权所有,谢绝全文转载--但您可以在您的网站上添加到该教程的链接. 在之前的教程中,您已经实现了继承.本教程引入了当你在使用实体框架Code

Vue入门系列(五)Vue实例详解与生命周期

[入门系列] [本文转自] http://www.cnblogs.com/fly_dragon Vue的实例是Vue框架的入口,其实也就是前端的ViewModel,它包含了页面中的业务逻辑处理.数据模型等,当然它也有自己的一系列的生命周期的事件钩子,辅助我们进行对整个Vue实例生成.编译.挂着.销毁等过程进行js控制. 5.1. Vue实例初始化的选项配置对象详解 前面我们已经用了很多次 new Vue({...})的代码,而且Vue初始化的选项都已经用了data.methods.el.comp

Android视频录制从不入门到入门系列教程(三)————视频方向

运行Android视频录制从不入门到入门系列教程(二)————显示视频图像中的Demo后,我们应该能发现视频的方向是错误的. 由于Android中,Camera给我们的视频图片的原始方向是下图这个样子的: 就是说,即使你是竖着拿手机的,Camera提供给你的视频图像的方向还是上图那样横着的图片. 我们可以通过下述方向改变Camera提供的视频图像的方法: camera.setDisplayOrientation(90); 让图像顺时针旋转90度,视频图像的方向就正常的. 本篇文章DEMO下载.