we also using `var self = this;` to avoid bind