js-setter-&-getter

在mvvm框架中,数据双向绑定的底层实现中会用到setter和getter,javascript的中的setter和getter可以实现:

  • 当获取对象的属性值时可以触发get方法
  • 当为对象的属性赋值时可以触发set方法

主要有如下4种实现方式:

对象初始化时定义

var obj = {
    a: 1,
    get b() {
        return this.a;
    },
    set b(v) {
        this.a = v;
    }
};
console.log(obj.b);
obj.b = 2;
console.log(obj.b);

Object.create

var proto = {a : 1};
var obj = Object.create(proto, {
    b: {
        get: function () {
            return this.a;
        },
        set: function (v) {
            this.a = v;
        }
    }
});
console.log(obj.b);
obj.b = 2;
console.log(obj.b);

Object.prototype.__defineGetter__(非标准) && Object.prototype.__defineSetter__(非标准)

var obj = { a: 1 };
obj.__defineGetter__("b", function () {
    return this.a;
});
obj.__defineSetter__("b", function (v) {
    this.a = v;
})
console.log(obj.b);
obj.b = 2;
console.log(obj.b);

Object.defineProperty

var obj = { a: 1 }
Object.defineProperty(obj, "b", {
    get: function () {
        return this.a;
    },
    set: function (v) {
        this.a = v;
    }
});
console.log(obj.b);
obj.b = 2;
console.log(obj.b);

以上示例中

  • obj.b 获取 b 属性值时就会触发 get 方法
  • obj.b = 2 为 b 属性赋值值就会触发 set 方法

在某些业务场景中,用户在文本框输入之后,会触发oninput方法进行校验,标红等。但是如果使用js为input赋值却无法触发这些方法,那么就可以使用setter,getter来实现。

js修改input元素的value值时触发set方法

<input id="xf" type="text" name="tt" value="1" />
<script type="text/javascript">
var inputProto = HTMLInputElement.prototype;
Object.defineProperty(inputProto, "value", {
    set: function (value) {
        var newValue = arguments.length ? value : this.value;
        var node = this.attributes.value;
        if (!node || newValue !== node.value) {
            var event = document.createEvent("Event");
            event.initEvent("input", true, true);
            this.setAttribute("value", newValue);
            this.style.color = 'red'
            if (document.documentElement.contains(this)) {
                this.dispatchEvent(event);
            }
        }
    }
});
xf.oninput = function () {
    console.log("fire event oninput!");
}
xf.value = 2;
</script>

上诉代码,当使用js修改input元素的value值时,触发set方法,使input的文字变成红色,并且触发oninput事件。

注意

上诉代码只在chrome下测试有效,其他浏览器的兼容方式可自行搜索。