2015-04-03 4 views
1

Я тестирую классы в ES6 с использованием traceur, но он не работает, как я ожидал.Справочные методы из другого класса в traceur

Я пытаюсь использовать метод в качестве ссылки в другом классе, но когда он называется, я получаю ссылку на класс вызывающего абонента при чтении значения this.

Вот мой код:

class A { 
    constructor(anotherMethod){ 
     this.anotherMethod = anotherMethod; 
     this.name = "A"; 
    } 
    myMethod(){ 
     console.log(this.name); 
     this.anotherMethod(); 
    } 
} 

class B { 
    constructor(){ 
     this.a = new A(this.myMethod); 
     this.name = "B"; 
    } 
    myMethod(){ 
     console.log(this.name); 
    } 
} 

var c = new B(); 
c.a.myMethod(); 

Мой ожидаемый журнал:

A 
B 

Но это показывает:

A 
A 
+0

возможно дубликат [Как получить доступ к правильной \ 'это \'/контекст внутри обратного вызова?] (HTTP: //stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) –

+0

* ", но когда он называется, я получаю ссылку на класс вызывающего абонента при чтении значения 'this'" * Это просто, как это работает в JavaScript. См. Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this –

+0

@FelixKling Я это понимаю. Но это сбивает с толку, потому что у вас нет универсальной переменной для доступа к текущему экземпляру класса. Вы не можете полагаться на эту переменную, если не уверены в том, как ваши методы будут использоваться другими. – Igor

ответ

2

В классе В, при выполнении функции конструктора:

this.a = new A(this.myMethod); 

Вы на самом деле установка метод myMethod В к А. Когда запускается конструктор, в

this.myMethod, устанавливается в anotherMethod в. Теперь, если вы попробуете распечатать this.a в своем конструкторе B, вы получите name : A. Что на самом деле ссылки на класс А.

Теперь, когда вы пытаетесь выполнения метода, c.a.myMethod(), As A содержит ссылку на class A, это, вызывающий myMethod из A. Внутри этого метода this будет ссылаться на текущий объект контекста выполнения который является A. Вот почему вы видите A в обеих консолях.

Короче говоря, вы назначаете функцию только A и не устанавливаете контекст.

Вы можете заставить fat arrow используя ниже:

class B { 
    constructor(){ 
     this.a = new A(this.myMethod); 
     this.name = "B"; 
    } 

    myMethod =() => { 
      console.log(this); 
    } 
} 

Теперь вы получите желаемый результат. Но, к сожалению, traceur не поддерживает его. Только babel поддерживает fat arrow внутренние функции, входящие в состав .

По предложению Феликса Кинг: Binding контекст, используя bind более чем достаточно в настоящее время

class B { 
    constructor(){ 
     this.a = new A(this.myMethod.bind(this)); 
     this.name = "B"; 
    } 

    myMethod() { 
      console.log(this); 
    } 
} 
+0

Хорошо, но это не ожидаемое поведение классов, не так ли?Если вы напишете аналогичный код на других языках, он будет работать. В coffeescript он работает, если вы используете жирную стрелу, но трассировка не поддерживает жирную стрелу в методах или не делает? – Igor

+0

Восстанавливает «Неожиданный токен». – Igor

+0

Я просто попытался использовать 'babeljs.io'. – mohamedrias