如果我想使用流畅的函数链来支持对象属性的赋值。例如:
foo.width(500).height(250).margin({left:5,right:10});
我显然可以创建一个函数定义,如:
margin(value) {
this.config.margin = value;
return this;
}
但是,如果我希望能够支持上述功能链接,但也直接分配如下:
foo.margin = {left:5,right:10};
我可以通过添加如下的setter来添加此支持:
set margin(value) {
this.config.margin = value;
}
但你不能拥有一个同名的setter和一个函数,显然setter只能用于文字赋值操作,而函数定义只适用于流畅的API方法。
有没有办法在语法上优雅地使用JS ES6?
我已经包含了一个小提琴,演示了流利和文字作业运算符的工作示例。唯一的问题?我不得不求助于使用不同的命名签名来增加API表面...如果可能的话我想避免这种情况。
答案 0 :(得分:2)
如果您愿意使用额外的两个字符检索属性值,那么您可以这样做:
export class Foo {
constructor() {
this.config = {
width:500,
height: 400
};
}
get width() {
return function(value) {
if (arguments.length) {
this.config.width = value;
return this;
}
return this.config.width;
};
}
set width(value) {
this.config.width = value;
}
}
let foo = new Foo();
console.log(foo.width());
foo.width = 600;
console.log(foo.width());
console.log(foo.width(250).width());
基本上,getter返回一个函数,该函数在使用参数调用时设置值,或者在没有参数的情况下调用它时返回值。这与API jQuery为.text()
和.html()
以及许多其他内容提供的类似,但它为您提供了直接分配给属性的附加选项。我不会真的推荐这个,因为能够foo.width = 5;
而不是var w = foo.width;
会让人感到困惑,但是我无法找到一个完全实现你的目标的好方法。 #39;重新尝试。
答案 1 :(得分:1)
你可以同时拥有两者。您只需坚持命名约定:
class Thing {
constructor() {
this._property = 0;
}
get property() {
return this._property;
}
set property(property) {
this._property = property;
}
setProperty(property) {
this.property = property;
return this;
}
}
这样你就可以吃蛋糕了。