Пишет ли класс JavaScript, в котором один метод может как получить, так и установить свойство, плохую практику? - PullRequest
2 голосов
/ 24 марта 2019

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

Я уже реализовал это на jsfiddle, также размещен по адресу:

https://jsfiddle.net/97g16hq3/7/

В частности, методы *Я имею в виду 1008 * и y(y = null).

class Vector {
    constructor( x, y ) {
    this._x = x
    this._y = y
  }

  x(x = null) {
    if (x) {
        this._x = x
    } else {
        return this._x
    }
  }

  y(y = null) {
    if (y) {
        this._y = y
    } else {
        return this._y
    }
  }

}

const myVec = new Vector( 1, 2 )

console.log(myVec)

// Get the vector
console.log('x: ', myVec.x())
console.log('y: ', myVec.y())

// Set the vector
myVec.x(3)
myVec.y(4)

// Get the vector
console.log('new vector')
console.log('x: ', myVec.x())
console.log('y: ', myVec.y())

Ответы [ 4 ]

1 голос
/ 24 марта 2019

Если вы спрашиваете конкретно о получении / настройке, то я бы предпочел использовать свойства getter / setter вместо стандартных методов, перегруженных альтернативным поведением. Таким образом, синтаксис на сайте «call» проясняет, что происходит.

class Vector {
    constructor( x, y ) {
    this._x = x
    this._y = y
  }

  get x() {
    return this._x
  }
  set x(x) {
    this._x = x
  }
  get y() {
    return this._y
  }
  set y(y) {
    this._y = y
  }
}

const myVec = new Vector( 1, 2 )

console.log(myVec)

// Get the vector
console.log('x: ', myVec.x)
console.log('y: ', myVec.y)

// Set the vector
myVec.x = 3
myVec.y = 4

// Get the vector
console.log('new vector')
console.log('x: ', myVec.x)
console.log('y: ', myVec.y)

В общем, я бы избегал такого перегруженного поведения, особенно если поведение сильно отличается. Это добавляет путаницу к API. ИМО, имя метода должно описывать, что происходит.

1 голос
/ 24 марта 2019

Лучше идти по стандарту и использовать get и set .

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

С технической точки зрения, с вашим подходом все в порядке.jQuery широко его использует: .val () , .text () , .height () - только пример.

Библиотекабыл там целую вечность, и, насколько я знаю, никто никогда не замечал никаких недостатков по этому поводу.

0 голосов
/ 24 марта 2019

Я вижу три проблемы с этим классом.

  1. Имо.самая большая проблема с этим кодом не в этой части x(x = null) {...}, а в этой

    if (x) {
        this._x = x
    } else {
        return this._x
    }
    

    Давайте начнем с самого очевидного: vector.x(0) устанавливает значение x в 0?А как насчет vector.x("0")?

    Затем, когда вы добавляете логику в свою функцию, чтобы всегда приводить аргумент к числу, как насчет NaN, "", [], +[], {}, null and undefined?И поверьте мне, некоторые из этих значений окажутся там.

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

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

  3. И это связано с # 2.Что для этого вы используете class Vector.Я бы сделал это как можно более легким и просто использовал бы для этого литералы:

    const myVec = {x: 1, y: 2};

И один советв дороге ваш код не содержит много ;, вы должны начать их использовать.Даже если движок вставляет их в основном правильно, в конечном итоге будут ситуации, когда ваш код не будет означать то, что вы имели в виду без них.

0 голосов
/ 24 марта 2019

Это не значит, что вы присваиваете значение:

x(x = null) { // it's default value for x is null

Таким образом, значение аргумента x устанавливается равным null, если вы не передаете значение или undefined.

Проверьте параметры по умолчанию для справки.

Изменить:

Это имеет значение по вашему требованию. Следующее устанавливает новое значение, если оно имеет значение:

if (x) {
  this._x = x
} else {
  return this._x
}

Но это установит значение, и ему все равно, будет ли оно null, undefined или что-то еще:

this._x = x // may result in `null`, `undefined`, ...

Но на самом деле нет необходимости устанавливать значение по умолчанию для x: x=null. Потому что вы просто проверяете это с помощью if(x){.

В некоторых случаях вы можете, в частности, проверить null, и в этом случае установка значения по умолчанию для x будет способом:

if(x===null){
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...