How to use "this" of class in "callbacks" in ES6? - javascript

I'm using Babel with ES2015. And want to use this inside callback inside method.
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/
I'm getting
TypeError: this is undefined
because as far as I understand this refers to the callback function in x(). As a solution I use
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/
And get
xxx
This is solution, but if you have mass of code it's getting very confusing and hard to write. Is there any better solution for using this? Or any other discipline for ES6 for using callbacks and this.

Look into arrow functions, and especially the way this is handled by arrow functions in comparison to classic functions.
class baz {
constructor() { this.bar = "xxx"; }
foo() {
x(() => {
console.log(this.bar);
});
}
}
Your solution using classic functions would not work if bar was changed between the call to x and the call to the callback.
This is how you should do it with classic functions
class baz {
constructor() { this.bar = "xxx"; }
foo() {
const self = this;
x(function () {
console.log(self.bar);
});
}
}
Or you could use bind, I suppose.
class baz {
constructor() { this.bar = "xxx"; }
foo() {
x((function () {
console.log(this.bar);
}).bind(this));
}
}

Related

how to use a variable in in an object in a javascript class

How do I make foo() work?
file1.js:
module.exports = class Example{
constructor(something){
this.something = something
}
functions ={
foo(){
return this.something
}
}
}
file2.js:
const Example = require('./file1.js')
const object = new Example("among")
console.log(object.foo())
First: you have to access those functions via .functions since that's where they live
Second, this will not be correct, so you can either
Make foo an arrow function
or you can .bind(this) to a function - like with bar in this code
you can't use .bind when using function property shorthand though - i.e. foo() { return this.something }.bind(this) - but you can bind it in the constructor
See the code for all three solutions - and why you need to bind the non arrow functions
class Example{
constructor(something){
this.something = something;
// bat needs to be bound here
this.functions.bat = this.functions.bat.bind(this);
}
functions ={
// "this" will be correct here
foo: () => this.something,
// bar needs to be bound to "this"
bar: function() { return this.something }.bind(this),
// you can't bind a shorthand property function though
bat() { return this.something },
// this is what happens with no bind
baz() { return this.something },
}
}
const object = new Example("among")
console.log('foo', object.functions.foo())
console.log('bar', object.functions.bar())
console.log('bat', object.functions.bat())
console.log('baz', object.functions.baz())
Remove functions:
class Example{
constructor(something){
this.something = something;
}
foo(){
return this.something
}
}
const object = new Example("among")
console.log(object.foo())

get function execution context

I have a function foo:
function foo() {
return 'foo';
}
While foo got executed is there a way to know if foo was called inside object declaration ? I want to distinguish these two cases:
var bar = {
prop1: foo()
}
var var1 = foo();
Here's one approach demonstrating the suggestions in the comments and assuming you'd rather call bar.prop1 instead of bar.prop1().
function foo (ctx) {
console.log(ctx == window)
return 'foo'
}
class Bar {
get prop1() {
return foo(this)
}
}
var var1 = foo(this);
var bar = new Bar();
bar.prop1;

Define a const in class constructor (ES6) [duplicate]

This question already has answers here:
Declaring static constants in ES6 classes?
(19 answers)
Closed 7 years ago.
Is there a way I can define a const in the constructor of a class?
I tried this:
class Foo {
constructor () {
const bar = 42;
}
getBar = () => {
return this.bar;
}
}
But
var a = new Foo();
console.log ( a.getBar() );
returns undefined.
You use static read-only properties to declare constant values that are scoped to a class.
class Foo {
static get BAR() {
return 42;
}
}
console.log(Foo.BAR); // print 42.
Foo.BAR = 43; // triggers an error
Simply defining a constant in the constructor won't attach it to the instance, you have to set it using this. I'm guessing you want immutability, so you can use getters:
class Foo {
constructor () {
this._bar = 42;
}
get bar() {
return this._bar;
}
}
Then you can use it like you normally would:
const foo = new Foo();
console.log(foo.bar) // 42
foo.bar = 15;
console.log(foo.bar) // still 42
This will not throw an error when trying to change bar. You could raise an error in a setter if you want:
class Foo {
constructor () {
this._bar = 42;
}
get bar() {
return this._bar;
}
set bar(value) {
throw new Error('bar is immutable.');
}
}
The problem is with "bar" scoping - it scoped to constructor:
'use strict';
class Foo {
constructor () {
const bar = 42;
this.bar = bar; // scoping to the class
}
getBar () {
return this.bar;
}
}
var a = new Foo();
console.log ( a.getBar() );

How to call Parent Method from the Overriding Method in Child class

How can I access a method from a parent class that was overridden in the child class?
In My example below I want to call the bar.my_name() method inside the overriding
method in foo.my_name()
function bar() {
this.my_name = function() {
alert("I Am Bar");
}
}
function foo() {
this.my_name = function() {
alert("I Am Foo");
//access parent.my_name()
}
}
foo.prototype = Object.create(bar.prototype);
foo.prototype.constructor = foo;
var test = new foo();
test.my_name();
You could do this:
(new bar()).my_name.call(this);
I think you're a little confused about how prototypes work though, as they're not really helping you here.
This might be slightly better:
var bar = {
my_name: function () {
console.log('bar name');
}
};
var foo = Object.create(bar);
foo.my_name = function () {
console.log('foo name');
bar.my_name.call(this);
};
Or if you want to use constructors, something like this:
function Bar () {}
Bar.prototype.my_name = function () {
console.log('bar name');
};
var foo = Object.create(Bar.prototype);
foo.my_name = function () {
console.log('foo name');
bar.my_name.call(this);
};
But I'm not really sure what you're trying to do or why, so with more context it will be easier to give you better advice.
One of possible solutions is to move the method to the base class prototype.
function bar() {
}
bar.prototype.my_name = function() {
alert("I am bar");
}
function foo() {
}
foo.prototype = Object.create(bar.prototype);
foo.prototype.my_name = function() {
alert("I Am Foo");
bar.prototype.my_name.call(this);
}
foo.prototype.constructor = foo;
var test = new foo();
test.my_name();

How to get 'this' value of caller function?

If I have a function like this:
function foo(_this) {
console.log(_this);
}
function bar() {}
bar.prototype.func = function() {
foo(this);
}
var test = new bar();
test.func();
then the test instance of bar gets logged.
However, for this to work I have to pass the this in the bar.prototype.func function. I was wondering whether it is possible to obtain the same this value without passing this.
I tried using arguments.callee.caller, but this returns the prototype function itself and not the this value inside the prototype function.
Is it possible to log the test instance of bar by only calling foo() in the prototype function?
If the question is 'without passing this (by any means)' then answer is no
value can be passed by alternative methods though. For example using global var (within Bar class) or session or cookies.
function bar() {
var myThis;
function foo() {
console.log(myThis);
}
bar.prototype.func = function() {
myThis = this;
foo();
}
}
var test = new bar();
test.func();
I think calling foo within the context of bar should work:
function foo() {
console.log(this.testVal);
}
function bar() { this.testVal = 'From bar with love'; }
bar.prototype.func = function() {
foo.call(this);
}
var test = new bar();
test.func(); //=> 'From bar with love'
You can do this without changing the external function, but you must change the way you call it.
You can't get the context of the caller, but you can set the this property on a function you call with the method apply or call. See this reference for an explanation on this.
function foo()
{
console.log( this );
}
function bar()
{
bar.prototype.func = function func()
{
foo.apply( this );
};
}
var test = new bar();
test.func();
Usually if this is used, it's in an object oriented context. Trying to call a method of an object with another this might indicate poor design. Explain a bit more what you are trying to achieve for more applicable design patterns.
For an example of a javascript OOP paradigm, check my answer here.
What about this?
"use strict";
var o = {
foo : function() {
console.log(this);
}
}
function bar() {}
bar.prototype = o;
bar.prototype.constructor = bar;
bar.prototype.func = function() {
this.foo();
}
var test = new bar();
test.func();
Or this:
"use strict";
Function.prototype.extender = function( o ){
if(typeof o == 'object'){
this.prototype = o;
}else if ( typeof o == 'function' ) {
this.prototype = Object.create(o.prototype);
}else{
throw Error('Error while extending '+this.name);
}
this.prototype.constructor = this;
}
var o = {
foo : function() {
console.log(this);
}
}
function bar() {}
bar.extender(o);
bar.prototype.func = function() {
this.foo();
}
var test = new bar();
test.func();

Categories