ECMAscript 6:观察 class 属性的变化
ECMAscript 6: watch changes to class properties
假设我有一个 class 定义如下:
class MyClass {
constructor (a) {
this.a = a;
}
_onPropertyChanged() {
// do something
}
}
每当 MyClass 实例的 属性 "a" 发生变化时,我想触发该实例的 _onPropertyChanged 方法。
使用 ECMAscript 6 实现此目的的最佳(最高性能)方法是什么?
没有'best'方法,实际方法总是取决于最终目标。
在其简单(且性能足够)的形式中,它是:
class MyClass {
constructor (a) {
this.a = a;
}
get a() {
return this._a;
}
set a(val) {
this._a = val;
this._onPropertyChanged('a', val);
}
_onPropertyChanged(propName, val) {
// do something
}
}
这是一个简单的示例,说明您可以针对这种情况和单个 属性 执行哪些操作。
class MyClass {
constructor (a) {
this._a = a;
}
set a(value) {
let hasChanged = (this._a !== value);
this._a = value;
//Assumes value is primitive. Customize for objects
if(hasChanged) this._onPropertyChanged();
}
_onPropertyChanged() {
// do something
}
}
最简单的事情就是像所说的那样为属性定义一个setter和一个getter。但是,如果您已经定义了 setter.
,它将不起作用
另一种方法是非标准的 Object.prototype.watch,它只能在 Gecko 中原生使用。如果你想将它的支持带到大多数其他浏览器,你可以使用一个小而强大的 Andrea Giammarchi's library.
最好的方法是重新定义 filed/property,但在这种情况下你会遇到一些陷阱,比如 'find owner of this prop'。您可以使用 this 解决方案进行完全安全的 属性 重新定义。
主要思想是重新定义 属性 如果存在:
Object.defineProperty(target, name, {
get() { return get(ownPropertyDescriptor.get.call(target)); },
set(val) {
let _val = set.call(this, val);
if (_val != undefined)
ownPropertyDescriptor.set.call(target, _val);
},
configurable: true
});
或根据 symbol
类型创建新的 属性:
var indexer = Symbol(name);
target[indexer] = target[name];
Object.defineProperty(target, name, {
get() {
var val = target[indexer];
var _val = get(val);
return _val;
},
set(val) {
let _val = set.call(this, val);
arget[indexer] = set(_val);
},
configurable: true
});
Full method is part of complex solution for property-redefining.
假设我有一个 class 定义如下:
class MyClass {
constructor (a) {
this.a = a;
}
_onPropertyChanged() {
// do something
}
}
每当 MyClass 实例的 属性 "a" 发生变化时,我想触发该实例的 _onPropertyChanged 方法。 使用 ECMAscript 6 实现此目的的最佳(最高性能)方法是什么?
没有'best'方法,实际方法总是取决于最终目标。
在其简单(且性能足够)的形式中,它是:
class MyClass {
constructor (a) {
this.a = a;
}
get a() {
return this._a;
}
set a(val) {
this._a = val;
this._onPropertyChanged('a', val);
}
_onPropertyChanged(propName, val) {
// do something
}
}
这是一个简单的示例,说明您可以针对这种情况和单个 属性 执行哪些操作。
class MyClass {
constructor (a) {
this._a = a;
}
set a(value) {
let hasChanged = (this._a !== value);
this._a = value;
//Assumes value is primitive. Customize for objects
if(hasChanged) this._onPropertyChanged();
}
_onPropertyChanged() {
// do something
}
}
最简单的事情就是像
另一种方法是非标准的 Object.prototype.watch,它只能在 Gecko 中原生使用。如果你想将它的支持带到大多数其他浏览器,你可以使用一个小而强大的 Andrea Giammarchi's library.
最好的方法是重新定义 filed/property,但在这种情况下你会遇到一些陷阱,比如 'find owner of this prop'。您可以使用 this 解决方案进行完全安全的 属性 重新定义。
主要思想是重新定义 属性 如果存在:
Object.defineProperty(target, name, {
get() { return get(ownPropertyDescriptor.get.call(target)); },
set(val) {
let _val = set.call(this, val);
if (_val != undefined)
ownPropertyDescriptor.set.call(target, _val);
},
configurable: true
});
或根据 symbol
类型创建新的 属性:
var indexer = Symbol(name);
target[indexer] = target[name];
Object.defineProperty(target, name, {
get() {
var val = target[indexer];
var _val = get(val);
return _val;
},
set(val) {
let _val = set.call(this, val);
arget[indexer] = set(_val);
},
configurable: true
});
Full method is part of complex solution for property-redefining.