функция, возвращающая функцию как свойство

1

Я знаю, что иногда бывает полезно, чтобы функции возвращали другие функции, чтобы вам не приходилось повторять себя, увеличивать модульность и т.д.
Но какой смысл в этом фрагменте (один из многих) здесь из библиотеки three.js?

Object.assign( Matrix4.prototype, {

...

    applyToBufferAttribute: function () {

        var v1 = new Vector3();

        return function applyToBufferAttribute( attribute ) {

            for ( var i = 0, l = attribute.count; i < l; i ++ ) {

                v1.x = attribute.getX( i );
                v1.y = attribute.getY( i );
                v1.z = attribute.getZ( i );

                v1.applyMatrix4( this );

                attribute.setXYZ( i, v1.x, v1.y, v1.z );

            }

            return attribute;

        };

    }(),

...

} );

"Inlined" applyToBufferAttribute не используется повторно в другом месте.

  • 0
    Что такое: ... ?
  • 0
    Это может быть просто стиль разработчика - сделать ваш код легко пригодным для повторного использования / расширения - довольно хорошая привычка, потому что теоретически это облегчает дальнейшую разработку.
Показать ещё 5 комментариев
Теги:

2 ответа

1
Лучший ответ

Возвращаемая функция становится методом, да. Целью обертывания его в IIFE является скрыть переменную v1, сделав ее тем, что C будет называть "статической переменной": независимо от того, сколько объектов Matrix4 вы создаете, независимо от того, сколько раз вы вызываете applyToBufferAttribute, будет только один экземпляр v1, и он не будет доступен, кроме функции applyToBufferAttribute.

Для этого мы можем только догадываться, но, вероятно, Vector3 затрат на выделение и освобождение для этого объекта Vector3, предполагая, что applyToBufferAttribute с некоторой частотой. Учитывая, что three.js является библиотекой WebGL, каждый небольшой оптимизатор помогает.

0

Вот как вы "спрячьте" переменную во внешнюю область.

v1 больше не виден вне вашего модуля, и вы убедитесь, что никто не будет его нарушать.

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

Альтернативой было бы сделать полный объект fledge и сделать v1 readonly, но вы часто не потрудитесь сделать такой объект. Таким образом, это быстрый способ инкапсулировать некоторую переменную.

Второй альтернативой будет добавление v1 к возвращаемому объекту.

function applyToBufferAttribute() {
    if (!this.v1) {
        this.v1 = new Vector3();
    }
    ...
 }

Но это также связано с тем, что v1 видимо снаружи и делает код более хрупким.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню