How to rewrite this IIFE into an ES6 class? - javascript

So I have this IIFE, and for the sake of consistence with other ES6 classes I rewrote for a plugin, I also want to rewrite this into using ES6 Class syntax. Can anyone show me how to do it?
Foo = (function(){
Foo.bar = function(a, b){
baz = new this(a, b);
return baz;
}
function Foo(a, b){
this.a = a;
this.b = b;
}
return Foo;
})();

It would be a simple
class Foo {
constructor(a, b) {
this.a = a;
this.b = b;
}
static bar(a, b) {
return new this(a, b);
}
}

The function created by the IIFE can be just as well created using a plain function declaration and property assignment:
function Foo(a, b) {
this.a = a;
this.b = b;
}
Foo.bar = function(a, b) {
baz = new this(a, b);
return baz;
}
var foo = new Foo('FooA', 'FooB');
console.log(foo.a + ':' + foo.b);
var baz = Foo.bar('BazA', 'BazB');
console.log(baz.a + ':' + baz.b);
Using the class syntax:
class Foo {
constructor(a, b) {
this.a = a;
this.b = b;
}
static bar(a, b){
baz = new this(a, b);
return baz;
}
}
var foo = new Foo('FooA','FooB');
console.log(foo.a + ':' + foo.b);
var baz = Foo.bar('BazA', 'BazB');
console.log(baz.a + ':' + baz.b);
Unfortunately I can't actually run this code as the site I'm currently on has SOE versions of Firefox and IE that don't recognise the class syntax. So please update if it's faulty.

Related

Cannot access property of an object created inside function of another object in javascript

function Method1(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
}
Method1.prototype = {
add: function() {
let x = this.a * Method2.r + this.b + this.c;
console.log(x);
}
}
function Method2(a, b, c, r) {
this.r = r;
this.obj = new Method1(a, b, c);
}
Method2.prototype = {
print: function() {
this.obj.add();
}
}
let x = new Method2(1, 2, 3, 4);
x.print();
In the above sample code, I want to use the variable r of Method2 inside of Method1's add function.
Can anyone please tell me where I am doing wrong and how to solve this? I need to access r inside add()
A workaround for you is to declare this.r for Method1. This way Method1 has can accept the r from Method2 and use it in the add function. See the attached snippet.
function Method1(a, b, c, r) {
this.a = a;
this.b = b;
this.c = c;
this.r = r;
}
Method1.prototype = {
add: function() {
let x = this.a * this.r + this.b + this.c;
console.log(x);
}
}
function Method2(a, b, c, r) {
this.r = r;
this.obj = new Method1(a, b, c, r);
}
Method2.prototype = {
print: function() {
this.obj.add();
}
}
let x = new Method2(1, 2, 3, 4);
x.print();
Consider making r in Method2 a static variable so that you can use it globally like this:
function Method1(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
}
Method1.prototype = {
add: function() {
let x = this.a * Method2.r + this.b + this.c;
console.log(x);
}
}
function Method2(a, b, c, r) {
Method2.r = r; // This is the only change you need to make
this.obj = new Method1(a, b, c);
}
Method2.prototype = {
print: function() {
this.obj.add();
}
}
let x = new Method2(1, 2, 3, 4);
x.print();
Did a little changes to your code:
function Method1(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
};
Method1.prototype.add = function(r){
let x = this.a * r + this.b + this.c;
console.log(x);
};
function Method2(a, b, c, r) {
this.r = r;
this.obj = new Method1(a, b, c);
}
Method2.prototype.print= function() {
this.obj.add(this.r);
};
The problems were
You were defining prototype functions wrong so instead of
Method2.prototype = { print: function() { this.obj.add(); }}
you should use:
Method2.prototype.print = function() {this.obj.add();}
Method2 is independent of Method1, so in order to use the "r" from Method2 in Method1 it needs to be passed from Method2 to Method1.

Experiment: Can a JavaScript instance be a constructor itself & have its own set of instances?

let bar;
function foo(){
this.x=x;
this.y=y;
}
bar=new foo(1,2);
/*Since all functions in javascript are objects.
Why can't an instance an object be a constructor itself?*/
!function bar(a,b){
this.a=a;
this.b=b;
}(); // (1)
let bar1=new bar(3,4);
console.log(bar1.a);
(1): Using a named IIFE, can bar be an instance and a constructor at the same time?
It's just a fun trick to exploit the language's freedom to see if it is a possibility, any other ways of doing this?
It sounds like you are looking for a constructor-function-returning function:
function makeBar(x, y) {
function Bar(a, b) {
this.a = a;
this.b = y + b;
}
Bar.x = x;
return Bar;
}
var Bar1 = makeBar("bar1", 2);
console.log(Bar1.x); // "bar1"
var myBar1 = new Bar1(1, 2); // Bar { a: 1, b: 4 }
console.log(myBar1 instanceof Bar1); // true
var Bar2 = makeBar("bar2", 0);
var myBar2 = new Bar2(3, 3); // Bar { a: 3, b: 3 }
console.log(myBar2 instanceof Bar1); // false
To make makeBar not a factory function but a constructor with a working prototype, you'd have to use
function Foo(x, y) {
function Bar(a, b) {
this.a = a;
this.b = y + b;
}
Object.setPrototypeOf(Bar, Foo.prototype);
Bar.x = x;
return Bar;
}
Foo.prototype.log = function() {
console.log("I'm "+this.name);
};
var Bar = new Foo("bar", 2);
Bar.log();
console.log(Bar instanceof Foo); // true
var myBar = new Bar(1, 2);
console.log(myBar instanceof Bar); // true
Can a JavaScript instance be a constructor itself & have its own set of instances?
Sure, a function is an instance of Function and a constructor is a function.
So you can just have
const instance1 = new Function("a", "this.a = a;");
const instance2 = new instance1("foo");
console.log(instance2.a); // "foo"
If you need instance1 to be more than a raw Function, you can even extend this constructor:
class MyFunc extends Function {
doSomethingMore(){ console.log("I'm doing more"); }
}
const instance1 = new MyFunc("a", "this.a = a;");
instance1.doSomethingMore();
const instance2 = new instance1("foo");
console.log(instance2.a); // "foo"
But I can't see a clear reason why you'd ever want to do that...
(Note that dynamically creating a function via the Function constructor is generally less "performant" than at parse time through function expression or statement.)
In your code, since bar is declared with let, it can't be re-declared as a function declaration in the same scope.
If you wanted to do this, you could have foo explicitly return a function, which could then be called with new:
function foo(x, y) {
this.x = x;
this.y = y;
return function bar(a, b) {
this.a = a;
this.b = b;
};
}
const bar = new foo(1, 2);
const bar1 = new bar(3, 4);
console.log(bar1.a);

JS Class: smartest way to create a variable inside a class without being called by the constructor

I want to create a variable inside a javascript class without the necessity to call it by a variable with the constructor.
for example, we have a class A that takes in 2 inputs (a and b). a and b are summed and the result is appended to an array arr. Where´s the best place to declare the array?
class A {
constructor(a,b) {
this.a = a;
this.b = b;};
do_something(this.a, this.b) {
let c = this.a + this.b;
arr.append(c);
return arr;}
};
where should i initialize arr without having it to be called form the outside ?
At the beginning of the class definition, also you can not have this.a and this.b as parameters of the do_something.
class A {
arr = []
constructor(a,b) {
this.a = a
this.b = b
}
do_something() {
const c = this.a + this.b
this.arr.push(c)
return [this.arr, c]}
}
const obj = new A(1,2)
console.log(obj.do_something())

Function that gets it's properties

How can I create a function where it gets it's property?
For example:
myfunc = function(){
alert(this.a + ":" + this.b);
};
myfunc.a = 5;
myfunc.b = 6;
The results is 5:6
There are two ways. The first, is as others have mentioned is to name the parameters in your function delcaration:
function foo(a, b) {
alert(a + ':' + b);
}
foo('hello', 'world'); // Output "hello:world"
Another way however is that a variable is available which contains all function parameters, called arguments.
function bar() {
alert(arguments[0] + ':' + arguments[1]);
}
bar('hello', 'world'); // Output "hello:world"
It should be noted that while it looks like an array, the arguments variable is not an instance of the JavaScript Array object, the only Array property available to use with arguments is .length.
This could be done with a closure:
var myFunc = (function(a, b) {
return function() {
console.log(a + ":" + b);
}
})(5, 6)
myFunc();
This can be expanded via prototype to create class like behaviour:
var myFunc = (function () {
function myFunc(a, b) {
if (a === void 0) { a = 5; }
if (b === void 0) { b = 6; }
this.a = a;
this.b = b;
}
myFunc.prototype.log = function () {
console.log(this.a + ":" + this.b);
};
return myFunc;
}());
var a = new myFunc();
a.log();
new myFunc().log();
new myFunc(1, 10).log();
//ACCESS ATTRIBUTE
console.log("ACCESSING", a.a);
//OVERWRITE ATTRIBUTE
a.a = 11;
//ACCESS ATTRIBUTE
console.log("ACCESSING", a.a);
a.log();
Try this:
myfunc = function(){
alert(this.a + ":" + this.b);
};
myfunc.call({a: 5, b: 6});
When you use the call function, the first parameter is your function's this and the second parameter is your function. The call function just call you function and assign {a: 5, b: 6} to myfunc's this.

Javascript: How to store a declared function in a variable?

I'm learning Javascript and wondering if it's possible to store a declared function in a variable to be used later?
For context,
function add(a, b) {
return a + b;
}
var addTogether = _.partial(add, 1);
doSomething() // returns a promise that resolves to a 2
.then(addTogether); // expect to return 3
Is there a way to achieve this?
var Add = function (a, b)
{
return a + b;
}
var result = Add (2, 3);
Absolutely. Functions ARE data in JavaScript.
var foo = function(a, b) {
return a + b;
}
Is perfectly legitimate.
function add(a, b) {
return a + b;
}
var foo = add;
console.log(foo(5,10));
console.log(add(10, 20));
You can also use ES6 syntax to store anonymous functions in constants, like so:
const add = (a, b) => a + b;
const addOne = a => add(a, 1);
console.log(add(5, 10)); // 15
console.log(addOne(5)); // 6

Categories

Resources