使用ES6 getter和setter而不是getProperty/setProperty约定的理由是什么?

Gaj*_*jus 15 javascript ecmascript-6

class Foo {
    getName = () => this.name;

    setName = (name) => this.name = name;
}
Run Code Online (Sandbox Code Playgroud)

class Foo {
    get name () {
        return this.name;
    }

    set name (name) {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以想到ES6吸气剂处于劣势的几个例子,例如

您不能编写将根据参数值返回值的getter:

/**
 * Returns an instance of Card associated with an element.
 *
 * @param {HTMLElement} element
 * @return {Card|undefined}
 */
getCard = (element) => {
    return _.find(this.index, {
        element: element
    });
};
Run Code Online (Sandbox Code Playgroud)

没关系,如果你使用这个和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;
Run Code Online (Sandbox Code Playgroud)

缺点是,您访问的属性可能需要大量计算能力(因此应该被记忆)或者每次访问它时都会发生变化,这是不直观的.

最后,getter/setter不支持箭头功能.示例无效:

class Foo {
    get name = () => {
        return this.name;
    }

    set name = (name) => {
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

这使他们暴露于背景问题.

什么是使用ES6 getter和setter的优势在传统的get{PropertyName}set{PropertyName}抽象?

Tim*_*rry 13

您无法区分直接属性访问和方法访问.

这是对他们有利的主要论据.

编写经典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/setters解决了这个问题.某些东西作为对象的直接属性可读的事实不再告诉您有关该属性的实现的任何信息.它最初可能是一个字段,但最近变成了ES6属性访问器,而没有更改API.该属性的实现对代码库的其余部分是隐藏的,因此更容易更改.

缺点是,您访问的属性可能需要大量计算能力(因此应该被记忆)或者每次访问它时都会发生变化,这是不直观的.

你是对的,这是一种风险.这也是任何getX()的问题; 有一个强烈的约定,暗示像'getName()'这样漂亮的简单方法不应该在幕后做昂贵的事情,即使它们是方法,如果你打破它,你几乎肯定会最终把人赶出去(包括你自己,6个月后)

迁移到属性并不会改变这一点,但是你认为ES6意味着你不再保证对简单的属性访问是安全的.答案实际上只是你必须确保你(以及其他所有人)坚持常规和最小惊讶的原则:与现有的简单看起来的getter和setter一样,ES6属性访问者应该做简单便宜的事情,并且不应该有奇怪的别处的副作用.


小智 4

没有任何特定的事情不能使用getMethod()and执行setMethod(),但它允许不同的代码样式。例如,您可以使用 aget fooset foo编写:

obj.foo++;
Run Code Online (Sandbox Code Playgroud)

它将先调用 getter,然后再调用 setter。例如,您当然可以让该set函数验证该值是否在特定范围内。传统的代码如下所示:

obj.setFoo(obj.getFoo() + 1);
Run Code Online (Sandbox Code Playgroud)

您无法区分直接属性访问和方法访问。

这就是重点。我认为如果某样东西真的很贵,你就不应该使用吸气剂。