效果:实时监听data.num的值,根据该值改变盒子的背景色。
代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type="./statics/js/jquery.js"></script>
<title>two-way binding</title>
<style>
.test1 {
width: 200px;
height: 200px;
background-color: bisque;
margin: 50px;
transition: all .6s;
}
</style>
</head>
<body>
<div class="test1"></div>
<script>
var data = { _num: 1 }
Object.defineProperty(data, "num", {
get: function () {
return this._num;
},
set: function (value) {
console.log(`data.num:` + value)
if (value == this._num) {
$(".test1").css("background-color", "red")
} else {
$(".test1").css("background-color", "yellow")
}
}
})
$(".test1").hover(function () {
data.num = 2
}, function () {
data.num = 1
})
</script>
</body>
</html>
es5的getter和setter方法
在ES5中新增了一个Object.defineProperty,直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。
Object.defineProperty(obj, prop, descriptor)
基于ES5的getter和setter可以说几乎完美符合了要求。为什么要说几乎呢?
首先IE8及更低版本IE是无法使用的,而且这个特性是没有polyfill的,无法在不支持的平台实现,这也是基于ES5getter和setter的Vue.js不支持IE8及更低版本IE的原因。也许有人会提到avalon,avalon在低版本IE借助vbscript一些黑魔法实现了类似的功能。
除此之外,还有一个问题就是修改数组的length,直接用索引设置元素如items[0] = {},以及数组的push等变异方法是无法触发setter的。
如果想要解决这个问题可以参考Vue的做法,在Vue的observer/array.js中,Vue直接修改了数组的原型方法。