Object.observe 简介

作者:yangchunwen

Object.observe 是一个提供数据监视的API,在 chrome 中已经可以使用。是 ECMAScript 7 的一个提案规范,官方建议的是“谨慎使用”级别,但是个人认为这个API非常有用,例如可以对现在流行的MVVM框架作一些简化和优化。虽然标准还没定,但是标准往往是滞后于实现的,只要是有用的东西,肯定会有越来越多的人去使用,越来越多的引擎会支持,最终促使标准的生成。

可以做什么

从observe字面意思就可以知道,这玩意儿就是用来做观察者模式之类的东东。

简单地说,就是观察一个对象的变化,在被观察者变化时作出一些回调。

实际应用中,可以优化数据模型(model)和网页试图(view)的双向绑定。

语法

语法很简单:

Object.observe(obj, callback)
obj

obj就是你要监听的数据模型(例如一个ajax接口对应的数据)

callback

callback就是数据模型变化后触发的回调(例如网页视图的变化)

callback函数的参数形式
  • name: 被修改的属性名称
  • object: 修改后该对象的值
  • type: 表示对该对象做了何种类型的修改,可能的值为"add", "update", "delete", "reconfigure"
  • oldValue: 对象修改前的值。该值只在"update"与"delete"有效

实例:

感兴趣可以跑一下下面简单的代码,你就知道各个参数的作用了

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
	</head>
	<body>
		<script>
			var obj = {};
			Object.observe(obj, function (changes) {
				changes.forEach(function (change) {
					console.log('变化的属性:  ' + change.name);
					console.log('变化的类型?: ' + change.type);
					console.log('旧值:  ' + change.oldValue);
					console.log('新值:  ' + change.object[change.name]);
				});
			});
		</script>
	</body>
</html>

实现MVVM

当然这里不是要取代MVVM框架,只是想通过Object.observe来实现一些性能上的优化。

Angular中有一个叫“脏值检查”的东西,大概的原理就是只要任何时候数据发生了变化,这个库都会通过一个digest或者change cycle去检查变化是否发生了。在Angular中,一个digest循环意味着所有所有被监视的表达式都会被循环一遍以便查看其中是否有变化发生。

用以下代码,大大优化了脏值检查

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>real MVVM</title>
	</head>
	<body>
		<form id="person">
			<input type="text" name="name" placeholder="名字">
			<input type="text" name="age" placeholder="年龄">
		</form>
		
		<script>
			var view = document.getElementById('person');
			var infomation = {};

			function bind(model, view) {
				Object.observe(model, function (changes) {
					changes.forEach(function (change) {
						var property = change.name;
						document.getElementsByName(property)[0].value = change.object[property];
					});
				});

				Array.prototype.slice.call(view.getElementsByTagName('input')).forEach(function (input) {
					input.addEventListener('input', function (e) {
						var input = e.target;
						if (input.tagName.toLowerCase() !== 'input') {
							return;
						}
						var property = input.getAttribute('name');
						model[property] = input.value;
					});
				});
			}

			bind(infomation, view);
		</script>
	</body>
</html>

脏值检查在任何数据可能发生变化的时候都必须要运行。这很明显并不是一个非常鲁棒的方法,并且任何实现脏值检查的途径都是有缺陷的(例如,在轮询中进行检查可能会造成视觉上的假象以及涉及到代码的紊乱情况)。脏值检查也需要注册一个全局的观察者,这很可能会造成内存泄漏,而Object.observe()会避免这一点。

参考

http://www.html5rocks.com/en/tutorials/es7/observe/

原文链接:http://ivweb.io/topic/556bd6bd79878a3b386dd01c

原创声明,本文系作者授权云+社区-专栏发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Coding01

简述我所理解的 PHP Trait

在常规的 PHP 开发中,我们都习惯于先编写一个通用的基类,实现基本的功能,然后扩展这个基类,创建更具体的子类,直接从父类继承实现。很多编程语言都使用这个继承层...

865
来自专栏Java进阶架构师

手把手带你实现JDK动态代理

业务接口Interface、业务实现类target、业务处理类Handler、JVM在内存中生成的动态代理类$Proxy0

661
来自专栏游戏开发那些事

【Unity游戏开发】用C#和Lua实现Unity中的事件分发机制EventDispatcher

  最近马三换了一家大公司工作,公司制度规范了一些,因此平时的业余时间多了不少。但是人却懒了下来,最近这一个月都没怎么研究新技术,博客写得也是拖拖拉拉,周六周天...

824
来自专栏程序猿DD

@FeignClient中的@RequestMapping也被Spring MVC加载的问题解决

问题描述 在之前发布的《Spring Cloud实战小贴士:Feign的继承特性(伪RPC模式)》一文中,我们介绍了如果使用Feign的继承特性来完成服务的提供...

36214
来自专栏余林丰

外观模式

 外观模式又称为门面模式,为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。我们还是用通俗的语言来解释这句话...

1648
来自专栏决胜机器学习

设计模式专题(四)——代理模式

设计模式专题(四)——代理模式 (原创内容,转载请注明来源,谢谢) 一、概述 代理模式(Proxy)是为其他对象提供一种代理,以控制这个对象的访问。即外系统...

3167
来自专栏Java技术分享

“金三银四”招聘期又要到了,快来复习JAVA题!!

由于各操作系统(windows,liunx等)支持的指令集,不是完全一致的。就会让我们的程序在不同的操作系统上要执行不同程序代码。Java开发了适用于不同操作...

1.3K13
来自专栏瓜大三哥

UVM模型(四)

UVM模型(四) ? 1.常用到的uvm_component uvm_driver:所有的driver都要派生自uvm_driver。driver的功能...

2329
来自专栏Android先生

Android中极简的js与java的交互库-SimpleJavaJsBridge

最近接触android中js与java交互的东西很多,当然它们之间的交互方式有几种,但是我觉得这几种交互方式都存在一定的不足,这是我决定编写SimpleJava...

773
来自专栏hbbliyong

C#基础知识回顾--委托事件

在上一篇看到他我一下子就悟了---委托,被人狂喷。说写的太空,没有什么内容之类的。所以准备在这里重写下,不过还是按着以前的方式尽量简单的写。这里我们以打篮球为...

3204

扫码关注云+社区