Използване на езикови помощници в 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 по подобен начин емулира set оператор.

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