2016-04-10 5 views
0

Я использую Babel с ES2015. И хотите использовать this внутри callback внутри метод.Как использовать этот «класс» в «обратных вызовах» в ES6?

class baz { 
    bar = "xxx"; 
    foo() { 
    x(function() { 
     console.log(this.bar); 
    }); 
    } 
} 

function x(callback) { 
    return callback(); 
} 
var y = new baz(); 
y.foo(); 

https://jsfiddle.net/dnthehnt/7/ Я получаю

TypeError: this is undefined

, потому что, насколько я понимаю, это относится к функции обратного вызова в x(). В качестве решения я использую

class baz { 
    bar = "xxx"; 
    foo() { 
    var bar = this.bar;//<===== 
    x(function() { 
     console.log(bar);//<===== 
    }); 
    } 
} 

function x(callback) { 
    return callback(); 
} 
var y = new baz(); 
y.foo(); 

https://jsfiddle.net/dnthehnt/6/ И получить

xxx

Это решение, но если у вас есть масса кода это становится очень запутанным и трудно писать. Есть ли лучшее решение для использования this? Или любая другая дисциплина для ES6 для использования обратных вызовов и этого.

+1

Это неправда ES2015. Это недопустимо со второй строкой ('bar =" xxx ";'). Вам понадобится A) Поместить этот код в 'constructor() {/*...*/}' и B) Использовать 'this.' перед' bar'. –

+0

Я думаю, что вложение '' 'конструктор'' не требуется. Я думаю, что лучше будет добавить переменные конструктора, которые будут добавлены при инициализации. – Shekspir

+2

Это не вопрос «мышления» так или иначе. Этот код недействителен. Код ES2015. Существует [Предложение 1-го этапа] (https://github.com/jeffmo/es-class-fields-and-static-properties), позволяющее определить поля экземпляра таким образом, но это только этап 1 (есть этапы 0-4, где 4 «готов к включению в следующую спецификацию»). Это не привело к отключению спецификации ES2016, и если она не прогрессирует быстрее, глядя на ES2017. Поэтому, хотя Вавилон может превзойти его (у Бабеля много нестандартных функций), синтаксис может измениться, прежде чем он будет введен в спецификацию, оставив вам нестандартный код. –

ответ

7

Посмотрите на функции стрелок, и особенно способ this обрабатывается функциями стрелок по сравнению с классическими функциями.

class baz { 
    constructor() { this.bar = "xxx"; } 
    foo() { 
    x(() => { 
     console.log(this.bar); 
    }); 
    } 
} 

Ваше решение с использованием классических функций не будет работать, если бар был изменен между вызовом x и вызовом функции обратного вызова.

Это, как вы должны делать это с классическими функциями

class baz { 
    constructor() { this.bar = "xxx"; } 
    foo() { 
    const self = this; 
    x(function() { 
     console.log(self.bar); 
    }); 
    } 
} 

Или вы могли бы использовать bind, я полагаю.

class baz { 
    constructor() { this.bar = "xxx"; } 
    foo() { 
    x((function() { 
     console.log(this.bar); 
    }).bind(this)); 
    } 
} 
+0

О, спасибо, ты прав. Я забыл, что() => {} не имеет прототипа. – Shekspir

+3

@Shekspir: Он не имеет ничего общего с прототипами. Функции Arrow не имеют обязательной привязки, поэтому они наследуют ее из контекста, в котором они созданы. –

+0

О, спасибо за информацию. – Shekspir

Смежные вопросы