Указатели класса в CoffeeScript? - PullRequest
1 голос
/ 13 февраля 2012

пытается выяснить, как написать следующее в CoffeeScript:

var foo = new function()
{

    var $this = this;

    $("#foo").click( this.clicked );

    this.clicked = function()
    {
        $this.alert( $(this).text() );
    };

    this.alert = function(message)
    {
        alert(message);
    };

};

К сожалению, я не могу понять, как в CoffeeScript я получаю доступ к указателю класса, «this», очевидно,не учитывает контекст и часто просто указывает на переменную, передаваемую вызываемым объектом.Поэтому я не могу написать приведенный выше скрипт на CoffeeScript.

Есть совет?Я не могу найти ничего полезного в документации, у вас есть @ указатели, но они также просто используют указатель "this" из текущего контекста, что делает его бесполезным.

Ответы [ 2 ]

3 голосов
/ 13 февраля 2012

Вы можете добавить методы непосредственно к @ в конструкторе для достижения того же эффекта:

class C
    constructor: ->
        $this = @
        @clicked = ->
            console.log @
            $this.alert 'pancakes'
    alert: (m) ->
        console.log m

c = new C
c.clicked()
c.clicked.call window​​​​​

Демонстрация: http://jsfiddle.net/ambiguous/Y8ZBe/

Обычно вы можете использовать связанный метод и аргумент «событие» в ситуациях, подобных этой:

class C
    clicked: (ev) =>
        @alert(ev.target.value)
    alert: (m) ->
        console.log m

c = new C
c.clicked(target: { value: 'pancakes' })
c.clicked.call window, target: { value: 'pancakes' }

Подобные вещи обычно появляются в обратных вызовах jQuery (или аналогичных), и они обычно имеют аргумент событиякоторый явно идентифицирует цель "this", чтобы вы могли использовать связанные функции.

Демо: http://jsfiddle.net/ambiguous/LafV2/

2 голосов
/ 14 февраля 2012

CoffeeScript по-прежнему является JavaScript.Ограничения this все еще применяются.Очевидно, что вы можете написать прямой перевод:

foo = ->
    self = this
    @clicked = ->
        self.alert $(this).text()
    @alert = (message) ->
        alert message
    $('#foo').click @clicked

Тем не менее, вы должны использовать прототипы (даже в javascript).С жирной стрелкой => вы можете привязать функцию к ее текущему контексту (но тогда вы потеряете ссылку на элемент):

foo = ->
    $('#foo').click (e) =>
        @clicked(e.target)

foo::clicked = (el) ->
    @alert $(el).text()

foo::alert = (message) ->
    alert message

Или используя абстракцию class (не более чем использование прототипав более красивой упаковке) и jQuery.proxy:

class Foo
    constructor: ->
        $('#foo').click $.proxy @clicked, this
    clicked: (e) ->
        @alert $(e.target).text()
    alert: (message) ->
        alert message

$.proxy @clicked, this можно заменить на @clicked.bind @ в современных браузерах / движках (см. Function.prototype.bind). * * тысяча двадцать-один

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