使用ES6 getter和setter而不是getProperty/setProperty约定的理由是什么?
What is the argument for using ES6 getters and setters over getProperty/setProperty convention?
class Foo {
getName = () => this.name;
setName = (name) => this.name = name;
}
和
class Foo {
get name () {
return this.name;
}
set name (name) {
this.name = name;
}
}
我可以想到几个例子,其中ES6 getter在中处于劣势,例如
你不能写一个getter来返回一个基于参数值的值:
/**
* Returns an instance of Card associated with an element.
*
* @param {HTMLElement} element
* @return {Card|undefined}
*/
getCard = (element) => {
return _.find(this.index, {
element: element
});
};
没关系,但是,如果你使用这个和ES6,你会引入代码风格不一致。
不能区分直接的属性访问和方法访问。
class Foo {
get name () {
return this.name;
}
get expensive () {
// An operation that takes a lot of computational power.
}
get randomValue () {
// Returns random value.
}
}
let foo = Foo();
foo.name;
foo.expensive;
foo.randomValue;
缺点是,您正在访问的属性可能需要大量的计算能力(因此应该记住),或者每次访问它都会发生变化,这不是直观的。
最后,getter/setter不能用于箭头函数。无效的例子:
class Foo {
get name = () => {
return this.name;
}
set name = (name) => {
this.name = name;
}
}
使它们暴露于上下文问题。
与传统的get{PropertyName}
和set{PropertyName}
抽象相比,使用ES6 getter和setter 的优势是什么?
不能区分直接的属性访问和方法访问。
这是对他们有利的主要理由。
编写经典java风格的OO代码的最奇怪的痛苦之一是,任何具有公开属性的对象都必须编写getter和setter,并且由此产生了大量的样本文件,特别是对于大型数据结构类型的对象(例如dto)。
所有这些的原因是,你不能只是让属性公开,因为否则你就不能在不破坏API的情况下向它们添加逻辑(例如,逻辑只允许设置某些值,或者以稍微不同的方式重构和存储属性,同时仍然暴露相同的外部API,或类似的)。请参阅https://softwareengineering.stackexchange.com/questions/176876/why-shouldnt-i-be-using-public-variables-in-my-java-class了解关于此的一些典型参数。
我认为你可以很轻松地说,近年来这种情况在逻辑上已经达到了极限,但这并不意味着它是错的;通过公开一个公共字段以供直接访问,你实际上是在公开如何存储该数据的内部实现,这意味着你不能再轻松或安全地更改它了。
ES6的getter/setter修复了这个问题。作为对象上的直接属性可读的事实不再告诉您有关该属性的实现的任何信息。它原本可以是一个字段,但最近变成了一个ES6属性访问器,没有更改API。该属性的实现对其他代码库是隐藏的,因此更容易更改。
缺点是,您正在访问的属性可能需要大量的计算能力(因此应该记住),或者每次访问它都会发生变化,这不是直观的。
你说得对,这是有风险的。这也是任何getX()的陷阱;有一种强烈的惯例表明,像'getName()'这样简单的方法不应该在后台做昂贵的事情,即使它们是方法,如果你打破了这个惯例,你几乎肯定会被人发现(包括你自己,6个月后)
移动到属性并没有改变这一点,但是你是对的,ES6意味着你不再保证简单的属性访问是安全的。答案是你必须确保你(和其他人)坚持惯例和最少意外原则:与现有的简单的getter和setter一样,ES6属性访问器应该做简单便宜的事情,并且不应该在其他地方有奇怪的副作用。
没有什么你不能用getMethod()
和setMethod()
做的事情,但是它允许不同的代码风格。例如,对于get foo
和set foo
,可以这样写:
obj.foo++;
会先调用getter,然后调用setter。当然,您可以使用set
函数然后验证该值是否在特定范围内。传统的代码看起来像:
obj.setFoo(obj.getFoo() + 1);
不能区分直接的属性访问和方法访问。
这就是问题的关键。我认为,如果某些东西真的昂贵,你就不应该为它使用getter。
- JavaScript命名约定;静态“;类或模块
- 用javascript记录传递给回调的参数的约定是什么
- 理解es6-mixin超类约定
- 命名约定的Web标准
- ES6迭代的约定
- Javascript中的变量命名约定;jQuery
- 角度模块依赖项的命名约定
- Javascript ES6 的属性和支持值命名约定
- 自定义咕噜声任务命名约定
- Laravel和变量命名约定(蛇格+骆驼格)
- 函数和回调的代码约定
- 当在JSON中使用包含对象的对象与对象数组时,可接受的约定是什么
- 如何设计API,使其符合REST约定和Ember.js方式
- JavaScript事件命名约定
- backbone.js的命名约定(在rails上)
- 我的backbone.js项目是否需要文件上的组件,或者这只是一种约定
- .NET 商店中的 JavaScript 命名约定
- 余烬中嵌套路由的控制器/路由约定
- 如何使用此命名约定验证表单客户端
- 使用ES6 getter和setter而不是getProperty/setProperty约定的理由是什么?