Использование языковых помощников в CoffeeScript при назначении прототипных свойств

У меня есть код CoffeeScript, который является кодом драйвера для neo4j. В том, что у него есть класс PropertyContainer, который имеет две функции get и set, которые перечислены как языковые помощники. а ниже находятся self и data , которые в основном являются прототипами свойств этого объекта. к ним можно получить доступ как a.self и a.data.

Чего я не понимаю, так это почему перед ними стоит get и set в следующем коде. get и set здесь четко определяют, считывается или записывается свойство, но как оно работает. В CoffeeScript вы определяете прототипические свойства как s prop_name: -> somecode, но если вы поместите get prop_name: -> somecode, не должно ли это изменить имя свойства на то, что возвращается после get prop_name. Я очень новичок в CoffeeScript, поэтому, возможно, я что-то упускаю. Пожалуйста помоги.

class PropertyContainer

    #
    # Construct a new wrapper around a Neo4j property container with the given
    # data directly from the server at the given Neo4j {GraphDatabase}.
    #
    # @private
    # @param db {GraphDatbase}
    # @param data {Object}
    #
    constructor: (db, data) ->
        @db = db
        @_request = db._request     # convenience alias

        @_data = data or {}
        @_data.self = data?.self or null

    ### Language helpers: ###

    get = (props) =>
        @::__defineGetter__ name, getter for name, getter of props
    set = (props) =>
        @::__defineSetter__ name, setter for name, setter of props

    ### Properties: ###

    #
    # @property {String} The URL of this property container.
    #
    # @todo This might be an implementation detail; should we remove it?
    #   If not, should it at least be renamed to just URL?
    #
    get self: -> @_data.self or null

    #
    # @property {Object} This property container's properties. This is a map
    #   of key-value pairs.
    #
    get data: -> @_data.data or null
    set data: (value) -> @_data.data = value

На самом деле это драйвер для Neo4j на основе REST API. Я не думаю, что это имеет какое-либо отношение к методу GET HTTP. Я проверил __defineGetter__ и __defineSetter__, их больше нигде нельзя увидеть во всей библиотеке, за исключением случаев, когда они используются аналогичным образом для других классов. Возможно, это какие-то внутренние прототипы прототипов CoffeeScript. Было бы здорово, если бы кто-нибудь мог пролить свет на это. Спасибо еще раз.


person vinit    schedule 26.12.2013    source источник
comment
я нашел место, которое объясняет назначение __defineGetter__ и __defineSetter__ ссылка кажется, я понял ту часть, что get и set — это просто вызовы функций для привязки свойств self и data к функциям, которые передаются в качестве аргумента значения ключа функциям get и set.   -  person vinit    schedule 26.12.2013


Ответы (1)


Класс CoffeeScript — это определение функции с кучей классовых вещей, расположенных сверху. Это означает, что вы можете поместить любой код внутри класса. Итак, если мы посмотрим на это:

class C
    f = -> #...
    f(6)

затем у нас есть частная функция f и простой вызов функции f(6).

Теперь, если мы добавим в смесь =>:

class C
    f = => #...

затем f привязывается к классу, так что @ внутри f будет самим C.

Теперь мы можем применить это к рассматриваемому классу:

class PropertyContainer
    #...

    get = (props) =>
        @::__defineGetter__ name, getter for name, getter of props
    set = (props) =>
        @::__defineSetter__ name, setter for name, setter of props

    get self: -> @_data.self or null

Итак, у нас есть две функции, get и set, которые изобилуют PropertyContainer, так что @ внутри get и set равно PropertyContainer. Затем у нас есть вызов функции get и добавление скобок и фигурных скобок, чтобы выделить структуру:

get({ self: (-> @_data.self or null ) })

мы должны начать видеть, что происходит. get self ... — это просто вызов функции get с параметром объекта, этот объект имеет единственный ключ (self), значением которого является функция.

Таким образом, весь вызов get self ... выглядит так:

PropertyContainer::__defineGetter__('self', -> @_data.self or null)

Затем, если мы посмотрим, что __defineGetter__ делает:

// Non-standard and deprecated way
var o = {};
o.__defineGetter__("gimmeFive", function() { return 5; });
console.log(o.gimmeFive); // 5

мы видим, что мы просто настраиваем o.self как псевдоним доступа для o._data.self, так что это:

o = new PropertyContainer(...)
o.self

действительно то же самое, что:

o = new PropertyContainer(...)
o._data.self

или, в более общем смысле, функция get позволяет вам отправить простой доступ к свойству функции. Вы также должны обратить внимание на «стандартные совместимые» примеры со страницы MDN:

// Using the get operator
var o = { get gimmeFive() {return 5}};
console.log(o.gimmeFive); // 5

Теперь мы видим, что get внутри PropertyContainer эмулирует get оператора JavaScript< /a> с помощью нестандартной функции __defineGetter__.

Функция set внутри PropertyContainer аналогичным образом эмулирует оператор JavaScript set.

person mu is too short    schedule 26.12.2013
comment
Спасибо @mu-is-too-short, отличное объяснение. описание => особенно полезно. - person vinit; 26.12.2013