Module variable as output of a method - javascript

I have a Javascript module:
const myModule = {
foo: this.initializeFoo(),
initializeFoo(){
// some loops and stuff to create an array
}
}
But I get an error: this.initializeFoo is not a function.
Is there some syntax I need to use to make this work, or is it not possible?

If you only intend to call it once and at the object's creation, then I would opt for a self-executing anonymous function:
const myModule = {
foo: (function () {
// some loops and stuff to create an array
})()
};
Alternatively, you can use arrow syntax instead:
const myModule = {
foo: (() => {
// some loops and stuff to create an array
})()
}
Example snippet:
const myModule = {
foo: (() => {
console.log('Processing');
return Array.apply(null, {length: 10}).map(Number.call, Number);
})()
};
// You can see that 'Processing' is only printed once
console.log(myModule.foo[2]);
console.log(myModule.foo[7]);

Declare the initializeFoo() function in outside of the Object
const myModule = {
foo : initializeFoo(),
}
function initializeFoo(){
return 'hi';
//or some loops and stuff to create an array
}
console.log(myModule)

If you can use ES6:
class MyModule {
constructor() {
this.initializeFoo();
}
initializeFoo() {
console.log('test');
// some loops and stuff to create an array
}
}
const myModule = new MyModule();
If you need to store the result of initializeFoo():
class MyModule {
constructor() {
this.initializeFoo();
}
initializeFoo(){
console.log('test');
this.initialVal = 2;
}
}
const myModule = new MyModule();
// 'test'
myModule.initialVal
// 2

Related

Add prototype of a fuction

I have some question about my node.js project.
What I'm trying to do is, add additional functionality to a function.
So, I added new functionality using prototype, but it failed.
Below is my current code.
[ someFeatures.js ]
const functionFoo = new Function()
const functionBar = new Function()
module.exports = { functionFoo, functionBar }
[ addFeatures.js ]
// Import fuction
const { functionFoo, functionBar } = require('./someFeatures.js')
// Add additional feature
functionFoo.prototype.addtionalFeatureA = foo => {
return someFunction(foo)
}
// Add additional feature
functionBar.prototype.addtionalFeatureB = foo => {
return someOtherFunction(foo)
}
module.exports = { functionFoo, functionBar }
[ Other files will use this feature ]
const { functionFoo } = require('./someFeatures.js')
const aaa = new functionFoo()
aaa.addtionalFeatureA('bbb')
The result is 'TypeError: Cannot read properties of undefined (reading 'prototype')'
Is there any solution to fix this issue? Thanks in advance!
change new Function
into empty function
let yourFunction = function () {}
and change this
function.prototype.additional = foo => { ... }
to this
function.prototype.additional = function (foo) {
...
}

JS advantages of module pattern?

I know it's a duplicate but I don't understand the other posts: I'm doing an exercise on freeCodeCamp that I don't understand, it's about modules: What's the advantage of doing this:
const motionModule = (function() {
return {
isCuteMixin: function(obj) {
obj.isCute = function() {
return true;
};
},
singMixin: function(obj) {
obj.sing = function() {
console.log("Singing to an awesome tune");
};
}
};
})();
instead of this:
const motionModule = {
isCuteMixin: function(obj) {
obj.isCute = function() {
return true;
};
},
singMixin: function(obj) {
obj.sing = function() {
console.log("Singing to an awesome tune");
};
}
};
One advantage is you can emulate private variables and methods which are not accessible from outside the returned object. This helps keeping the data and functionality together and avoids corruption of global namespace.
const motionModule = (function() {
let song = 'My song'; // private variable
function singTheSong() {
// private method
}
return {
isCuteMixin: function(obj) {
obj.isCute = function() {
return true;
};
},
singMixin: function(obj) {
obj.sing = function() {
console.log("Singing to an awesome tune" + song);
singTheSong();
};
}
};
})();
// cannot call singTheSong from here
Within a module, you would often want the methods to be able to access each other and shared variables. To do this in your 2nd example, you need to attach them to the object and access them via the this keyword, and also (within the mixin creating functions) use arrow functions to ensure this refers to the right object.
const motionModule = {
song: "La La La",
sing: function() {
console.log(this.song);
},
singMixin: function(obj) {
obj.sing = () => {
console.log(`Singing ${this.song}`);
};
}
};
const a = {};
motionModule.sing();
motionModule.singMixin(a);
a.sing();
Modern ES6 class declarations also require you to work in this way.
class MotionModule {
song = "La La La";
sing() {
console.log(this.song);
}
singMixin(obj) {
obj.sing = () => {
console.log(`Singing ${this.song}`);
};
}
}
const motionModule = new MotionModule();
motionModule.sing();
const a = {};
motionModule.singMixin(a);
a.sing();
As shown in another answer, the first example (an immediately invoked function expression) allows you to access other variables and methods defined within the module without using this, and gives you greater control over which methods and variables are accessible from outside the module.

How to create functions base on config in javascript class

I can defined readFoo in Foo class:
var myFormat = 'foo'
class Foo {
[ "read" + ((format) => format)(myFormat) ]() {
return 123;
}
}
is there any way how to define function base on config like:
var config = ['foo1', 'foo2']
class Foo {
config.map((name) => {
[ "read" + ((format) => format)(name) ]() {
return 123;
}
}
}
Will create functions readFoo1 and readFoo2.
You can iterate through the array and assign to the prototype afterwards:
var config = ['foo1', 'foo2']
class Foo {}
for (const name of config) {
Foo.prototype["read" + name] = function() {
return 123;
};
}
const f = new Foo();
console.log(f.readfoo1());

Applying proxy to an object

Hi, I am trying to transform an object into a proxy, without changing the reference to the object:
Here is a simple class:
class Foo {
constructor () {
this.a = 'bar'
}
}
const foo = new Foo()
Here is my Proxy:
const proxy = new Proxy(foo, {
get () {
return 'proxy-bar'
},
set () {
// Don't do anything
return true
}
})
Here is what a normal use of this proxy does:
console.log(foo.a) // bar
console.log(proxy.a) // proxy-bar
Now, I want to keep using foo, but with the capabilities of proxy. So I tried to use Object.assign which seems to work only for the getter, but not for the setter. Is their something I miss?
Object.assign(foo, proxy)
console.log(foo.a) // Getter works: proxy-bar
foo.a = 'proxy-proxy-bar'
console.log(foo.a) // Setter does not work: proxy-proxy-bar
You can apply the proxy in your constructor and return it :
class Foo {
constructor() {
this.a = 'bar';
return new Proxy(this, {
get() {
return 'proxy-bar'
},
set() {
// Don't do anything
return true
}
});
}
}
const foo = new Foo();
foo.a = 'proxy-proxy-bar';
console.log(foo.a); // proxy-bar

Is it possible to redefine a function after its setter is modified in the parent function?

I can only change the code within function a. For example if I have:
Object.defineProperty(window, 'App', { get: console.log.bind(null, 'World') });
WeChat will take my code and turn it into:
__wxJSEngine.App = console.log.bind(null, 'Hello')
g.App = __wxJSEngine.App
Object.defineProperty(g, 'App', {
set: ()=> {
console.error("You are not allow to modify App");
}
})
((App, Function, window) => {
'use strict';
function a() {
'use strict';
// *** I can only modify codes within this block ***
Object.defineProperty(window, 'App', { get: console.log.bind(null, 'World') });
// *** I can only modify codes within this block ***
}
function b() {
'use strict';
App();
}
a();
b();
})(g.App, ()=>(()=>({})), undefined);
Now, I want to modify App in function a, so I can change its behavior in function b, so it would print World instead of Hello.
Given how the code is structured, function b will not use the global App, but directly sandbox's argument.
This argument is accessible to a's scope and is not declared as a const.
So all you need to do, is to overwrite the value of the variable App from inside a, so that b can use your own value.
window.App = console.log.bind(null, 'Hello')
Object.defineProperty(window, 'App', {
set: ()=> {
console.error("You are not allow to modify App");
}
})
const sandbox = (App, Function, window) => {
'use strict';
function a() {
'use strict';
// *** I can only modify codes within this block ***
App = console.log.bind(null, 'World');
// *** I can only modify codes within this block ***
}
function b() {
'use strict';
App();
}
a();
b();
};
sandbox(window.App, ()=>(()=>({})), undefined);
Now, this won't change window.App value, but since this property has been defined as non-writable, non-configurable, there is nothing you can do to set it to something else.
Object composition is when you copy properties from one object to another. Object.assign() is the goto method.
const App = func => ({
salutation: () => {
return `${func.user}: ${func.HW}`;
}
});
const a = (user, greeting) => {
let func = {
user,
HW: greeting
};
return Object.assign(func, App(func));
};
const A = a('zer00ne', 'World');
console.log(A.user);
console.log(A.salutation());

Categories