Vector.js
Начиная с базового модуля Vector
, мы используем объекты для хранения свойств x
и y
, но мы уверены, что векторные операции add
difference
и scale
не видоизменяют объект;вместо этого всегда возвращается новый вектор -
const Vector = (x = 0, y = 0) =>
({ x, y })
Vector.add = (a = Vector (), b = Vector ()) =>
Vector
( a.x + b.x
, a.y + b.y
)
Vector.difference = (a = Vector (), b = Vector ()) =>
Vector
( a.x - b.x
, a.y - b.y
)
Vector.scale = ({ x, y } = Vector (), k = 1) =>
Vector
( x * k
, y * k
)
// ...
export default Vector
Field.js
Затем мы создаем модуль Field
, который зависит от Vector
.Опять же, мы гарантируем, что мы не используем изменяемые операции -
const Vector =
require ('./Vector')
const Field = (mass = 0, position = Vector ()) =>
({ mass, position })
Field.calculateForce = ({ mass, position:{ x, y } } = Field ()) =>
mass / (x ** 2 + y ** 2 + mass) ** 1.5
Field.disturbanceAcceleration = (origin, fields = []) =>
fields.reduce
( (acc, { mass, position }) =>
{ const v =
Vector.difference (position, origin)
const force =
Field.calculateForce (Field (mass, v))
return Vector.add
( acc
, Vector.scale (v, force)
)
}
, Vector ()
)
// ...
export default Field
Теперь для нашего решения -
import Vector from './Vector'
import Field from './Field'
const fields =
[ Field (140, Vector (100, 100))
, Field (140, Vector (200, 100))
, Field (140, Vector (150, 300))
]
Field.disturbanceAcceleration (Vector (), fields)
// { x: 0.007947635786319896, y: 0.007256173830876778 }
Использование аргументов по умолчанию дает нам чрезвычайно удобное использование наших типов данных.Это то, что мы не считаем само собой разумеющимся -
Vector () // { x: 0, y: 0 }
Vector () .x // 0
Vector () .y // 0
Vector (1, 2) .x // 1
Vector (1, 2) .y // 2
Field () // { mass: 0, position: { x: 0, y: 0 } }
Field () .mass // 0
Field () .position // { x: 0, y: 0 }
Field (100) .mass // 100
Field (100) .position // { x: 0, y: 0 }
Field (100, Vector (1, 2)) .mass // 100
Field (100, Vector (1, 2)) .position .x // 1
Field (100, Vector (1, 2)) .position .y // 2
myparticle.js
У вас может быть много субмодулей, и это нормально.Вероятно, вы захотите объединить подмодули в один больший модуль, возможно, тот, который мы назовем myparticle -
import Vector from './Vector'
import Field from './Field'
// ...
export { Vector, Field /*, ... */ }
Затем, когда мы используем его в нашем решении -
import { Vector, Field /*, ... */ } from ('myparticle')
// ...
Демонстрация кода
Разверните фрагмент ниже, чтобы проверить результаты в своем собственном браузере -
// Vector -------------------------------------------
const Vector = (x = 0, y = 0) =>
({ x, y })
Vector.add = (a = Vector (), b = Vector ()) =>
Vector
( a.x + b.x
, a.y + b.y
)
Vector.difference = (a = Vector (), b = Vector ()) =>
Vector
( a.x - b.x
, a.y - b.y
)
Vector.scale = ({ x, y } = Vector (), k = 1) =>
Vector
( x * k
, y * k
)
// Field -------------------------------------------
const Field = (mass = 0, position = Vector ()) =>
({ mass, position })
Field.calculateForce = ({ mass, position:{ x, y } } = Field ()) =>
mass / (x ** 2 + y ** 2 + mass) ** 1.5
Field.disturbanceAcceleration = (origin, fields = []) =>
fields.reduce
( (acc, { mass, position }) =>
{ const v =
Vector.difference (position, origin)
const force =
Field.calculateForce (Field (mass, v))
return Vector.add
( acc
, Vector.scale (v, force)
)
}
, Vector ()
)
// Demo -------------------------------------------
const fields =
[ Field (140, Vector (100, 100))
, Field (140, Vector (200, 100))
, Field (140, Vector (150, 300))
]
const result =
Field.disturbanceAcceleration (Vector (), fields)
console .log (result)
// { x: 0.007947635786319896, y: 0.007256173830876778 }
Простые объектные модули
Выше мы сделали функцию Vector
и затем присоединяемadd
, difference
и scale
в качестве свойств функции.Это работает в JavaScript, потому что функции являются объектами, и мы можем назначать свойства любым способом, который мы выберем.Этот дизайн позволяет нам конструировать векторы, используя Vector
в качестве функции конструктора, а затем вызывать Vector.add
, Vector.scale
и т. Д. Для наших операций, связанных с вектором. простой объект .Векторные операции add
, difference
и scale
могут быть добавлены в качестве свойств объекта.Затем конструктор можно добавить в качестве свойства make
или любого имени по вашему выбору -
// Vector.js
const make = (x = 0, y = 0) =>
({ x, y })
const add = ...
const difference = ...
const scale = ...
export { make, add, difference, scale }
Vector
больше не является функцией.Вместо этого конструктор экспортируется как make
.Теперь мы строим векторы, используя Vector.make
-
import Vector from './Vector'
const u =
Vector.make (1, 1) // must call Vector.make
const v =
Vector.make (2, 3) // must call Vector.make
Vector.add (u, v) // { x: 3, y: 4 }
Независимо от того, как вы решите упаковать свои модули, зависит только от вас, просто убедитесь, что оно согласовано.