Javascript: Почему геттеры используются над методами? - PullRequest
0 голосов
/ 02 июля 2018

Так что мне интересно, в чем разница между методами и геттерами?

Чтение документации Mozilla :

Иногда желательно разрешить доступ к свойству, которое возвращает динамически вычисленное значение, или вы можете захотеть отразить статус внутренняя переменная, не требующая использования явного метода звонки

Но разве они не достигают одного и того же? Почему один лучше другого?

Почему говорит:

var obj = {
    log: ['a', 'b', 'c'],
    get latest() {
    if (this.log.length == 0) {
      return undefined;
    }
    return this.log[this.log.length - 1];
  }
}

console.log(obj.latest);

Иногда предпочтительнее иметь метод latest () и вызывать obj.latest (). Если код запускается в обоих случаях, какой смысл? Разве они оба не динамичны?

Документация также гласит :

Геттеры дают вам возможность определить свойство объекта, но они делают не вычислять значение свойства, пока оно не будет доступно.

В чем именно разница между «доступным» и «вызываемым»? Метод не запускается до тех пор, пока не будет вызван, так же как свойство не доступно до тех пор, пока оно не включено? Так в чем же значение?

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Согласно документации для Object.defineProperty() на MSDN

Дескрипторы свойств, присутствующие в объектах, бывают двух основных типов: данные дескрипторы и дескрипторы доступа. Дескриптор данных является свойством это имеет значение, которое может или не может быть доступно для записи. Аксессор дескриптор - это свойство, описываемое парой геттер-сеттер функции. Дескриптор должен быть одним из этих двух вариантов; не может быть и.

И дескрипторы данных, и методы доступа являются объектами. Они разделяют следующие дополнительные клавиши:

настраивается true тогда и только тогда, когда тип этого дескриптора свойства может быть изменен, и если свойство может быть удалено из соответствующего объекта. По умолчанию false.

enumerable true тогда и только тогда, когда это свойство отображается при перечислении свойств соответствующего объекта. По умолчанию false.

Дескриптор данных также имеет следующие дополнительные ключи:

значение Значение, связанное со свойством. Может быть любым допустимым значением JavaScript (число, объект, функция и т. Д.). По умолчанию не определено.

доступный для записи true тогда и только тогда, когда значение, связанное со свойством, может быть изменено с помощью оператора присваивания. По умолчанию false.

Дескриптор средства доступа также имеет следующие дополнительные ключи:

get Функция, которая служит для получения свойства свойства, или неопределенная, если нет получения. Когда к свойству обращаются, эта функция вызывается без аргументов и с этим набором объекта, через который осуществляется доступ к свойству (это может быть не тот объект, для которого свойство определяется из-за наследования). Возвращаемое значение будет использоваться в качестве значения свойства. По умолчанию не определено.

set Функция, которая служит установщиком для свойства, или неопределенная, если установщика нет. Когда свойство присваивается, эта функция вызывается с одним аргументом (значение присваивается свойству) и с этим набором объекта, через который присваивается свойство. По умолчанию не определено.

Если дескриптор не имеет значения, доступен для записи, получить и установить ключи, он рассматривается как дескриптор данных. Если дескриптор имеет оба Значение или запись и получить или установить ключи, исключение.

Это означает, что get и set перехватывают вызовы доступа и вызовы назначения соответственно.

Очень хороший пример (и описание) здесь указывает на яркий пример того, когда это полезно.

Возьмите случай, когда у вас есть имя и фамилия на лице с общей потребностью в полном имени.

person.setLastName('Smith');
person.setFirstName('Jimmy');
person.getFullName(); // Jimmy Smith

Использование клавиш get и set дает возможность объявить объект следующим образом:

var person = {
    firstName: 'Jimmy',
    lastName: 'Smith',
    get fullName() {
        return this.firstName + ' ' + this.lastName;
    },
    set fullName (name) {
        var words = name.toString().split(' ');
        this.firstName = words[0] || '';
        this.lastName = words[1] || '';
    }
}

и присвоение ему, и доступ к нему следующим образом:

person.fullName = 'Jack Franklin';
console.log(person.firstName); // Jack
console.log(person.lastName) // Franklin
console.log(person.fullName) // Jack Franklin

Это позволяет разработчику взаимодействовать с полным именем, не оставляя случайно имя или фамилию неназначенной или неправильно назначенной.

Наконец,

Директива use strict будет обеспечивать попытки чтения и записи для атрибутов, определенных с помощью get или set соответственно. См. W3Schools .

"use strict";
var obj = {get x() {return 0} };

obj.x = 3.14;            // This will cause an error
0 голосов
/ 02 июля 2018

Обратите внимание, следующее мнение.

Метод получения предназначен для извлечения значения определенного свойства, и он позволяет вашему объекту иметь динамические свойства, основанные на значении других свойств, но в остальном вести себя так, как вы ожидаете, что свойства будут вести себя. Метод получения позволяет вам определить метод, который вызывается при доступе к этому свойству, даже если вы обращаетесь к нему с помощью обычных средств доступа к свойствам объекта, myObject.dynamicProp и myObject['dynamicProp'].

Геттеры предоставляются именно для этой цели. Если это цель метода, который вы пишете, используйте синтаксис getter.

Существуют методы, позволяющие делать другие вербальные, ориентированные на действие, а не просто возвращать какое-либо свойство объекта, который вы пишете.

Вы всегда можете написать метод для получения, но почему?

Так что это зависит от ваших намерений. Получатели задают намерение, и если ваше намерение состоит в том, чтобы предоставить динамическое свойство, которое ведет себя так же, как свойство объекта, тогда используйте метод получения вместо метода.

Надеюсь, это поможет!

Обновлено :

Несмотря на то, что здесь есть технический нюанс, и хотя я склонялся к использованию приведенных выше методов получения, я бы сказал, после дальнейшего размышления, что подход, который вы хотите использовать, зависит от вас:

(1) Вы хотите использовать обычные методы доступа для доступа к этому свойству? Вы в порядке с динамическими свойствами, которые скрывают некоторую логику? (Они на самом деле не «скрывают» логику как таковую, но выглядят как обычные реквизиты для звонящего). Затем используйте get().

(2) Вы хотите, чтобы ваше свойство было динамичным и более читабельным? Вы занимаетесь чем-то, кроме простого вычисления динамического свойства на основе текущих значений существующих свойств этого объекта? Вы в порядке вызова метода явно? Затем используйте метод, например, getLatest().

...