The function `this` doesn't work in module of nodejs - javascript

I create a module with following
module.exports = {
GetRandomNum:(Min,Max)=>{
var Range = Max - Min;
var Rand = Math.random();
return(Min + Math.round(Rand * Range));
},
mathCalculationtion:()=>{
var firstPlace = this.GetRandomNum(1, 9);
return firstPlace;
}
}
I run this above code and get an error at the line var firstPlace = this.GetRandomNum(1, 9);
at Object. mathCalculationtion (/home/sfud/projectland/lib/comlib.js)
Please help me, thank you.

You are using arrow functions. The this variable does exist within regular objects, but arrow functions pull their this from whatever this is when they're declared (unless you bind them, which would be an odd thing to do).
Change your functions to functions and it should work fine.
module.exports = {
GetRandomNum(Min,Max) {
var Range = Max - Min;
var Rand = Math.random();
return(Min + Math.round(Rand * Range));
},
mathCalculationtion() {
var firstPlace = this.GetRandomNum(1, 9);
return firstPlace;
}
}
Note: To use it this way, you will need to import the module and call the function with the . syntax.
// This will work
const myModule = require('./my-module');
console.log(myModule.mathCalculationtion());
// This will not work
const { mathCalculationtion } = require('./my-module');
console.log(mathCalculationtion());
This is because this within the function is whatever the x in x.myFunc() is. If you just call myFunc() directly, it has no idea which object to apply it to. If you want to get around this, either define your functions in your module separately and reference them by name in the module, then export each function, or you can use .bind().

Change this.GetRandomNum(1, 9) to module.exports.GetRandomNum(1, 9) or
declare your functions outside of the module.exports block:
var getRandomNum = (Min,Max) => {
var Range = Max - Min;
var Rand = Math.random();
return(Min + Math.round(Rand * Range));
}
var mathCalculationtion = () => {
var firstPlace = getRandomNum(1, 9);
return firstPlace;
}
then:
module.exports = {
getRandomNum,
mathCalculationtion
}

Use module.exports instead of this:
module.exports = {
GetRandomNum(Min,Max) {
var Range = Max - Min;
var Rand = Math.random();
return(Min + Math.round(Rand * Range));
},
mathCalculationtion() {
var firstPlace = module.exports.GetRandomNum(1, 9);
return firstPlace;
}
}
It works for me just fine in NodeJs v12.16.1.

Related

How to export variable inside a function to another module

I would like to generate an array and store the value inside a variable and export that variable in a way that i can acess it anywhere i want in my application.
const generateNewArray = () => {
var numberOfArrayItems = 40;
var currentArray = Array.from({ length: numberOfArrayItems }, () => Math.floor(Math.random() * 200) + 1);
return currentArray;
}
export { generateNewArray }
But, until right now i could only export the function. And when i invoke "generateNewArray" i get the function body as answer, and when i invoke "generateNewArray()" i get another random array, different from the original.
How can i acess the "currentArray" variable from anywhere in my application?
Thanks!
You need to create a local variable, set its value, and then export the variable itself:
const generateNewArray = () => {
var numberOfArrayItems = 40;
var currentArray = Array.from({ length: numberOfArrayItems },
() => Math.floor(Math.random() * 200) + 1);
return currentArray;
}
const myRandomArray = generateNewArray();
export { myRandomArray }

can i reduce my code using loop for varaible or array

now the repeating code problem has been solved but when executed the if condition function of moveHorse is being executed repeteadly. please help.
function moveHorse(horseId)
);
interval=setInterval(function(){moveHorse('horseID');},20);
}
now the repeating code problem has been solved but when executed the if condition function of moveHorse is being executed repeteadly. please help.
Pass in the element ID as the function parameter, then you can refactor the code to -
// TODO: rename your local variable name because now it doesn't need to be horse4, right?
function horseUp(horseElementId) {
var horse = document.getElementById(horseElementId);
// do the rest
}
function horseDown(horseElementId) {
var horse = document.getElementById(horseElementId);
// do the rest
}
function horseleft(horseElementId) {
var horse = document.getElementById(horseElementId);
// do the rest
}
To use the function, pass in the element Id
horseUp('horse4');
horseLeft('horse2');
and so on
Since the only part that appears to be different is the horse being changed, just pass that in. For example:
var horse4 = document.getElementById('horse4');
function horseUp(horse, moving) {
var horseTop = horse.offsetTop;
var random = Math.random() * 2.7 + 2;
horse.style.top = horseTop - 0.5 * random + 'px';
if (horseTop <= window.innerHeight * 0.05) {
clearInterval(interval4);
interval4 = setInterval(moving, 10);
}
}
There's a few other variables like interval4 that you'll need to figure out, but this should give you the general idea.
May use OOP:
function Horse(id) {
this.el = document.getElementById(id);
}
Horse.prototype={
move(x,y){
this.el.offsetTop+=(this.y=typeof y !=="undefined"?y:this.y);
this.el.offsetLeft+=(this.x=typeof x !== "undefined"?x:this.x);
},
up(){
this.move(0,0.5*Math.random() * 2.7 + 2* + 'px';
},
down(){ this.move(0,- 0.5* Math.random() * 2.4 + 2);},
left(){ this.move(0.5* Math.random() * 2.4 + 2,0);},
right(){ this.move(- 0.5* Math.random() * 2.4 + 2,0);},
setInterval(){
this.interval=setInterval(_=>this.move(),10);
}
}
use like this:
var horse4=new Horse("horse4");
horse4.setInterval();
horse4.left();

Chain custom javascript functions

After searching for quite some time, I still haven't found what I'm looking for.
There's a fair amount of examples that either require creating a new instance, or only have functions that don't return anything (which means the problem can be solved with returning this).
I hope the following example illustrates my point well:
// Say I have these functions
function aNumber(){
var max = 100, min = 0;
return (Math.floor(Math.random() * (max - min + 1)) + min);
}
function divideBy(_number, _divider){
return (_number / _divider);
}
function multiplyBy(_number, _multi){
return (_number * _multi);
}
function add(_number, _add){
return (_number + _add);
}
function subtract(_number, _sub){
return (_number - _sub);
}
// #########################################################
// I can do this with them
var test = aNumber();
test = divideBy(aNumber, 2);
test = add(aNumber, 5);
test = multiplyBy(aNumber, 3);
test = subtract(aNumber, 10);
// I would like to do this however:
var test = aNumber().divideBy(2).add(5).multiplyBy(3).subtract(10);
What would be the most efficient way to make the last line work?
Am I misinformed that this is possible without creating a new instance of something?
Yes, this requires changing the Prototype of an Object. Objects are instances. So you need to create an object to do this kind of thing.
function MyNum(value) {
this._val = value; // Having _variable is for denoting it is a private variable.
}
Initialize objects using:
var myNum = new MyNum(5);
And now using this, define these:
MyNum.prototype.divideBy = function () {}
MyNum.prototype.multiplyBy = function () {}
Don't forget to use return this; inside these functions.
Try like below for creating without instance and prototype keyword.
One more method is been added here you can set number or random number by default. if the number not specified.
var Calculator = {
setNumber: function(givenNumber) {
var max = 100,
min = 0;
this.number = (givenNumber) ? givenNumber : (Math.floor(Math.random() * (max - min + 1)) + min);
return this;
},
divideBy: function(_divider) {
this.number = (this.number / _divider);
return this;
},
multiplyBy: function(_multi) {
this.number = (this.number * _multi);
return this;
},
add: function(_add) {
this.number = (this.number + _add);
return this;
},
subtract: function(_sub) {
this.number = (this.number - _sub);
return this;
},
result: function () {
return this.number;
}
}
document.write('<pre>');
document.writeln(Calculator.setNumber(2).divideBy(2).add(5).multiplyBy(3).subtract(10).result());
document.writeln(Calculator.setNumber(4).divideBy(2).add(5).multiplyBy(3).subtract(10).number);
document.writeln(Calculator.setNumber().divideBy(2).add(5).multiplyBy(3).subtract(10).result());
document.write('</pre>');
Yes, you do need to create an instance of something. This can be a simple object literal, function constructor, etc...
The idea is that all of your methods are stored on some object, right? The only way to access those methods is to access them through that object. With this in mind, each function must RETURN the object that holds all of these methods.
A quick example
var myMethods = {
one: function() {
console.log('one');
// You can return 'this' or reference the object by name
return this;
// or
// return myMethods;
},
two: function() {
console.log('two');
return this;
}
};
myMethods.one().two().one().two();
//=> 'one', 'two', 'one', 'two'
Watch out when you reference the method directly, like so
var someMethod = myMethods.one;
someMethod() //=> undefined
This is because 'this' is now referencing the global object, which is another story for another day. Just watch out if you reference a method in this way.
Although it is generally not recommended to add functions to the prototype of JavaScript primitives, you can do what you are looking for by doing so.
function aNumber(){
var max = 100, min = 0;
return (Math.floor(Math.random() * (max - min + 1)) + min);
}
function divideBy(_number, _divider){
return (_number / _divider);
}
function multiplyBy(_number, _multi){
return (_number * _multi);
}
function add(_number, _add){
return (_number + _add);
}
function subtract(_number, _sub){
return (_number - _sub);
}
Number.prototype.divideBy = function(_divider){
return divideBy(this, _divider);
};
Number.prototype.multiplyBy = function(_multi){
return multiplyBy(this, _multi);
};
Number.prototype.add = function(_add){
return add(this, _add);
};
Number.prototype.subtract = function(_sub){
return subtract(this, _sub);
};
var test = aNumber().divideBy(2).add(5).multiplyBy(3).subtract(10);
Just like Praveen and Venkatraman said, I found the following posts about chaining, but there all have to declare a new instanse before accessing any methods for changing
method-chaining-in-javascript and beautiful-javascript-easily-create-chainable-cascading-methods-for-expressiveness
or you can use this implementation https://jsfiddle.net/ayinloya/zkys5dk6/
function aNumber() {
var max = 100;
var min = 0;
this._number = (Math.floor(Math.random() * (max - min + 1)) + min);
console.log("a init", this._number)
}
aNumber.prototype.divideBy = function(_divider) {
this._number = (this._number / _divider)
return this;
}
aNumber.prototype.multiplyBy = function(_multi) {
this._number = (this._number * _multi);
return this;
}
aNumber.prototype.add = function(_add) {
this._number = (this._number + _add);
return this;
}
aNumber.prototype.subtract = function(_sub) {
this._number = (this._number - _sub);
return this;
}
aNumber.prototype.ans = function() {
return this._number;
}
var a = new aNumber()
alert(a.add(2).subtract(1).ans())
If you don't want to pull in a library and want to have functions that are reusable (and not bind to a specific class, e.g. a Calculator). What you can do is to wrap the input into an array and then pass it through a series of map functions. In the end just take the first element and you will have your result.
function aNumber(){
var max = 100, min = 0;
return (Math.floor(Math.random() * (max - min + 1)) + min);
}
function divideBy(_number, _divider){
return (_number / _divider);
}
function multiplyBy(_number, _multi){
return (_number * _multi);
}
function add(_number, _add){
return (_number + _add);
}
function subtract(_number, _sub){
return (_number - _sub);
}
// #########################################################
var result = [aNumber()]
.map(item => divideBy(item, 2))
.map(item => add(item, 5))
.map(item => multiplyBy(item, 3))
.map(item => subtract(item, 10))
[0];
console.log(result);
This probably is not the most efficient way but usually speed is "good enough".

Javascript Float32 array throws Cannot read property '0' of null even though array is well defined

Here you can see the debug window: http://i.imgur.com/ZnfeKT1.png
As you can see, the array is NOT null and has in fact 2 elements. Why the hell am I getting that error ?
Edit: This code was written in C# and converted to JS via DuoCode:
WebGL.Vector2 = $d.declare("WebGL.Vector2", null, 62, $asm, function($t, $p) {
$t.cctor = function() {
$t.GLVector2 = vec2;
};
$t.ctor = function Vector2() {
this.vec = null;
};
$t.ctor.prototype = $p;
$p.get_X = function Vector2_get_X() {
return this.vec[0]; //this is line 777
};
$p.set_X = function Vector2_set_X(value) {
this.vec[0] = value;
return value;
};
$p.get_Y = function Vector2_get_Y() {
return this.vec[1];
};
$p.set_Y = function Vector2_set_Y(value) {
this.vec[1] = value;
return value;
};
$p.get_Magnitude = function Vector2_get_Magnitude() {
return Math.sqrt(this.get_X() * this.get_X() + this.get_Y() * this.get_Y());
};
$p.get_Normalized = function Vector2_get_Normalized() {
var m = this.get_Magnitude();
return WebGL.Vector2.op_Division(this, m);
};
$t.ctor$1 = function Vector2() {
this.vec = $d.array(System.Single, 2);
this.set_X(0);
this.set_Y(0);
};
$t.ctor$1.prototype = $p;
$t.ctor$2 = function Vector2(x, y) {
this.vec = $d.array(System.Single, 2);
this.set_X(x);
this.set_Y(y);
};
$t.ctor$2.prototype = $p;
$p.Rotated = function Vector2_Rotated(angle) {
var rad = Math.PI * angle / 180;
var cs = Math.cos(rad);
var sn = Math.sin(rad);
return new WebGL.Vector2.ctor$2(this.get_X() * cs - this.get_Y() * sn, this.get_X() * sn + this.get_Y() * cs);
};
$p.Transformed = function Vector2_Transformed(matrix) {
var ret = new WebGL.Vector2.ctor$1();
$t().GLVector2.transformMat3(ret.vec, this.vec, matrix.mat);
return ret;
};
$t.op_Multiply = function Vector2_op_Multiply(v, f) {
return new WebGL.Vector2.ctor$2(v.get_X() * f, v.get_Y() * f);
};
$t.op_Division = function Vector2_op_Division(v, f) {
return new WebGL.Vector2.ctor$2(v.get_X() / f, v.get_Y() / f);
};
$t.op_Addition = function Vector2_op_Addition(v1, v2) {
return new WebGL.Vector2.ctor$2(v1.get_X() + v2.get_X(), v1.get_Y() + v2.get_Y());
};
$t.op_Subtraction = function Vector2_op_Subtraction(v1, v2) {
return new WebGL.Vector2.ctor$2(v1.get_X() - v2.get_X(), v1.get_Y() - v2.get_Y());
};
$t.Dot = function Vector2_Dot(v1, v2) {
return v1.get_X() * v2.get_X() + v1.get_Y() * v2.get_Y();
};
$p.ToString = function Vector2_ToString() {
return String.Format("[{0}, {1}]", $d.array(System.Object, [this.get_X(), this.get_Y()]));
};
});
You're right, this is a bad behavior, but it happens because of an experimental feature in C# 6 (parameterless constructors). Usually C# forbids declaring default constructors for structs, that's why there must be an automatic default ctor that initializes the struct (and sets null to reference-type fields like the array "vec").
C# 6 added the option for primary constructors - but Microsoft already realized that it's too complicated and I believe they plan to abandon this feature for now.
DuoCode uses Roslyn for compilation and that's the reason for this behavior. Next releases of Roslyn and DuoCode probably will forbid this.
I would recommend that you make your Vector2 struct as an immutable struct with two fields (x, y) - that would work the best.
Disclaimer: I work with the DuoCode developers
Edit: Oops, it's called parameterless constructors
Okay the problem was the following: For some reason, DuoCode generates a default constructor for structs which initializes value types with null. My custom default constructor is ONLY called when I explicitly call Vector2 v = new Vector2(). This behavior is pretty unexpected and quite annoying to be honest. I hope this will be fixed in later releases.

how do i run a custom function on a string instead of an object

As a test I wrote this fn which works:
$.fn.doubleup = function(){
this.html(this.html()*2);
};
$('div').doubleup();
I tried to write a similar function to run on a number like below, but this doesn't work:
$.fn.doubleup2 = function(){
this = (this * 2);
};
var n = 2;
n.doubleup2();
Is it possible to write a fn that runs on variables or strings?
In your scenario, I wouldn't use jQuery at all. If you want to double up on say, numbers, then try using the Number.prototype property.
Number.prototype.doubleUp = function() {
return this * 2;
}
var num = 23;
console.log(num.doubleUp());
JavaScript already has great support for you to extend types with your own functionality, there is no need to use jQuery here.
EDIT:
Based on the comments, you could do this:
Object.prototype.doubleUp = function () {
if (this instanceof Number) {
return this * 2;
}
if (this instanceof String) {
return this * 4; // Just for example.
}
return this * 2; // Just for example.
};
var num = 23;
var num2 = "23";
console.log(num.doubleUp());
console.log(num2.doubleUp());

Categories

Resources