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 条评论
登录 后参与评论

相关文章

来自专栏恰同学骚年

《你必须知道的.NET》读书笔记一:小OO有大智慧

此篇已收录至《你必须知道的.Net》读书笔记目录贴,点击访问该目录可以获取更多内容。

372
来自专栏WeTest质量开放平台团队的专栏

Unity3d底层数据传递分析

这篇文章主要分析了在Mono框架下,非托管堆、运行时、托管堆如何关联,以及通过哪些方式调用。内存方面,介绍了什么是封送,以及类和结构体的关系和区别。

5332
来自专栏Albert陈凯

2018-07-19 如何重构“箭头型”代码如何重构“箭头型”代码

原文地址:https://coolshell.cn/articles/17757.html

926
来自专栏蛋未明的专栏

Node.js内存泄漏分析

1774
来自专栏ATYUN订阅号

NLP研究者的福音—spaCy2.0中引入自定义的管道和扩展

以前版本的spaCy很难拓展。尤其是核心的Doc,Token和Span对象。他们没有直接实例化,所以创建一个有用的子类将涉及很多该死的抽象(想想FactoryF...

3539
来自专栏技巅

Redis第一个版本源码分析-启动过程分析1

1705
来自专栏向治洪

Google V8引擎

V8的前世今生 V8是JavaScript渲染引擎,第一个版本随着Chrome的发布而发布(具体时间为2008年9月2日)。在运行JavaScript之前,相比...

2875
来自专栏CDA数据分析师

20个小招数教你如果快速完成Python 性能优化升级

使用python时,你是不是需要性能优化?今天C君给大家带来python性能优化的20条招数,建议收藏~

1042
来自专栏大内老A

WCF技术剖析之二十五: 元数据(Metadata)架构体系全景展现[元数据描述篇]

在[WS标准篇]中我花了很大的篇幅介绍了WS-MEX以及与它相关的WS规范:WS-Policy、WS-Transfer和WSDL,因为WCF元数据结构体系完全是...

1608
来自专栏灯塔大数据

干货 | Python 性能优化的20条招数

使用python时,你是不是需要性能优化?今天灯塔给你带来python性能优化的20条招数,记得收藏哟!

882

扫码关注云+社区